KVM: x86: Change __kvm_apic_update_irr() to also return if max IRR updated

This commit doesn't change semantics.
It is done as a preparation for future commits.

Signed-off-by: Liran Alon <liran.alon@oracle.com>
Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Signed-off-by: Liam Merwick <liam.merwick@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
This commit is contained in:
Liran Alon 2017-12-24 18:12:54 +02:00 коммит произвёл Radim Krčmář
Родитель fa59cc0038
Коммит e7387b0e27
3 изменённых файлов: 21 добавлений и 11 удалений

Просмотреть файл

@ -364,32 +364,41 @@ static u8 count_vectors(void *bitmap)
return count; return count;
} }
int __kvm_apic_update_irr(u32 *pir, void *regs) bool __kvm_apic_update_irr(u32 *pir, void *regs, int *max_irr)
{ {
u32 i, vec; u32 i, vec;
u32 pir_val, irr_val; u32 pir_val, irr_val, prev_irr_val;
int max_irr = -1; int max_updated_irr;
max_updated_irr = -1;
*max_irr = -1;
for (i = vec = 0; i <= 7; i++, vec += 32) { for (i = vec = 0; i <= 7; i++, vec += 32) {
pir_val = READ_ONCE(pir[i]); pir_val = READ_ONCE(pir[i]);
irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10)); irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10));
if (pir_val) { if (pir_val) {
prev_irr_val = irr_val;
irr_val |= xchg(&pir[i], 0); irr_val |= xchg(&pir[i], 0);
*((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val; *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val;
if (prev_irr_val != irr_val) {
max_updated_irr =
__fls(irr_val ^ prev_irr_val) + vec;
}
} }
if (irr_val) if (irr_val)
max_irr = __fls(irr_val) + vec; *max_irr = __fls(irr_val) + vec;
} }
return max_irr; return ((max_updated_irr != -1) &&
(max_updated_irr == *max_irr));
} }
EXPORT_SYMBOL_GPL(__kvm_apic_update_irr); EXPORT_SYMBOL_GPL(__kvm_apic_update_irr);
int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir) bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr)
{ {
struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_lapic *apic = vcpu->arch.apic;
return __kvm_apic_update_irr(pir, apic->regs); return __kvm_apic_update_irr(pir, apic->regs, max_irr);
} }
EXPORT_SYMBOL_GPL(kvm_apic_update_irr); EXPORT_SYMBOL_GPL(kvm_apic_update_irr);

Просмотреть файл

@ -75,8 +75,8 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
int short_hand, unsigned int dest, int dest_mode); int short_hand, unsigned int dest, int dest_mode);
int __kvm_apic_update_irr(u32 *pir, void *regs); bool __kvm_apic_update_irr(u32 *pir, void *regs, int *max_irr);
int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr);
void kvm_apic_update_ppr(struct kvm_vcpu *vcpu); void kvm_apic_update_ppr(struct kvm_vcpu *vcpu);
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
struct dest_map *dest_map); struct dest_map *dest_map);

Просмотреть файл

@ -5085,7 +5085,8 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256); max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
if (max_irr != 256) { if (max_irr != 256) {
vapic_page = kmap(vmx->nested.virtual_apic_page); vapic_page = kmap(vmx->nested.virtual_apic_page);
__kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page); __kvm_apic_update_irr(vmx->nested.pi_desc->pir,
vapic_page, &max_irr);
kunmap(vmx->nested.virtual_apic_page); kunmap(vmx->nested.virtual_apic_page);
status = vmcs_read16(GUEST_INTR_STATUS); status = vmcs_read16(GUEST_INTR_STATUS);
@ -8986,7 +8987,7 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
* But on x86 this is just a compiler barrier anyway. * But on x86 this is just a compiler barrier anyway.
*/ */
smp_mb__after_atomic(); smp_mb__after_atomic();
max_irr = kvm_apic_update_irr(vcpu, vmx->pi_desc.pir); kvm_apic_update_irr(vcpu, vmx->pi_desc.pir, &max_irr);
} else { } else {
max_irr = kvm_lapic_find_highest_irr(vcpu); max_irr = kvm_lapic_find_highest_irr(vcpu);
} }