mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Fixes for KVM/ARM for 4.0-rc5.
Fixes page refcounting issues in our Stage-2 page table management code, fixes a missing unlock in a gicv3 error path, and fixes a race that can cause lost interrupts if signals are pending just prior to entering the guest. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVBs95AAoJEEtpOizt6ddyAfoH/Rwj2T38ZDikImPpgfeFrmJs ZlWC+Z3akwjVHPv308/MsKdyashtA7OjiMp3DOheMFMYJay/ecgY/92vFCc6uh5S LDoXCbp+Pneth6C6bbU2Gw+aoCD07ZYCn9PeFq40MfpQUhCEGWhx41OFzHppqOZx e+jodHRE+sBVTFUtbz+HubAfcM46f/8bP7682CEKsVZPeTSiHyeojdZEglfB37MG ar/iC1/cyO/097vWaBqv1t1WZoHbWmMrDlzo5X+AtayVXFNdv4Ztw0Rz2kRhnLB8 8GXYawoSQoTN8FX1oyTyr5YWcWD7wDTzhcHsHS1xZHhvrdLCEcFrHeEWkuUlYjU= =YS6j -----END PGP SIGNATURE----- Merge tag 'kvm-arm-fixes-4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm Fixes for KVM/ARM for 4.0-rc5. Fixes page refcounting issues in our Stage-2 page table management code, fixes a missing unlock in a gicv3 error path, and fixes a race that can cause lost interrupts if signals are pending just prior to entering the guest.
This commit is contained in:
commit
f710a12d73
8 changed files with 105 additions and 75 deletions
|
|
@ -72,6 +72,8 @@ static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
|
|||
{
|
||||
if (!(lr_desc.state & LR_STATE_MASK))
|
||||
vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr |= (1ULL << lr);
|
||||
else
|
||||
vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr &= ~(1ULL << lr);
|
||||
}
|
||||
|
||||
static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu)
|
||||
|
|
@ -84,6 +86,11 @@ static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu)
|
|||
return vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr;
|
||||
}
|
||||
|
||||
static void vgic_v2_clear_eisr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr = 0;
|
||||
}
|
||||
|
||||
static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr;
|
||||
|
|
@ -148,6 +155,7 @@ static const struct vgic_ops vgic_v2_ops = {
|
|||
.sync_lr_elrsr = vgic_v2_sync_lr_elrsr,
|
||||
.get_elrsr = vgic_v2_get_elrsr,
|
||||
.get_eisr = vgic_v2_get_eisr,
|
||||
.clear_eisr = vgic_v2_clear_eisr,
|
||||
.get_interrupt_status = vgic_v2_get_interrupt_status,
|
||||
.enable_underflow = vgic_v2_enable_underflow,
|
||||
.disable_underflow = vgic_v2_disable_underflow,
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
|
|||
{
|
||||
if (!(lr_desc.state & LR_STATE_MASK))
|
||||
vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr);
|
||||
else
|
||||
vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr &= ~(1U << lr);
|
||||
}
|
||||
|
||||
static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu)
|
||||
|
|
@ -116,6 +118,11 @@ static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu)
|
|||
return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr;
|
||||
}
|
||||
|
||||
static void vgic_v3_clear_eisr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr = 0;
|
||||
}
|
||||
|
||||
static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr;
|
||||
|
|
@ -192,6 +199,7 @@ static const struct vgic_ops vgic_v3_ops = {
|
|||
.sync_lr_elrsr = vgic_v3_sync_lr_elrsr,
|
||||
.get_elrsr = vgic_v3_get_elrsr,
|
||||
.get_eisr = vgic_v3_get_eisr,
|
||||
.clear_eisr = vgic_v3_clear_eisr,
|
||||
.get_interrupt_status = vgic_v3_get_interrupt_status,
|
||||
.enable_underflow = vgic_v3_enable_underflow,
|
||||
.disable_underflow = vgic_v3_disable_underflow,
|
||||
|
|
|
|||
|
|
@ -883,6 +883,11 @@ static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
|
|||
return vgic_ops->get_eisr(vcpu);
|
||||
}
|
||||
|
||||
static inline void vgic_clear_eisr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vgic_ops->clear_eisr(vcpu);
|
||||
}
|
||||
|
||||
static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vgic_ops->get_interrupt_status(vcpu);
|
||||
|
|
@ -922,6 +927,7 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
|
|||
vgic_set_lr(vcpu, lr_nr, vlr);
|
||||
clear_bit(lr_nr, vgic_cpu->lr_used);
|
||||
vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
|
||||
vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -978,6 +984,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
|
|||
BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
|
||||
vlr.state |= LR_STATE_PENDING;
|
||||
vgic_set_lr(vcpu, lr, vlr);
|
||||
vgic_sync_lr_elrsr(vcpu, lr, vlr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -999,6 +1006,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
|
|||
vlr.state |= LR_EOI_INT;
|
||||
|
||||
vgic_set_lr(vcpu, lr, vlr);
|
||||
vgic_sync_lr_elrsr(vcpu, lr, vlr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1136,6 +1144,14 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
|
|||
if (status & INT_STATUS_UNDERFLOW)
|
||||
vgic_disable_underflow(vcpu);
|
||||
|
||||
/*
|
||||
* In the next iterations of the vcpu loop, if we sync the vgic state
|
||||
* after flushing it, but before entering the guest (this happens for
|
||||
* pending signals and vmid rollovers), then make sure we don't pick
|
||||
* up any old maintenance interrupts here.
|
||||
*/
|
||||
vgic_clear_eisr(vcpu);
|
||||
|
||||
return level_pending;
|
||||
}
|
||||
|
||||
|
|
@ -1583,8 +1599,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
|
|||
* emulation. So check this here again. KVM_CREATE_DEVICE does
|
||||
* the proper checks already.
|
||||
*/
|
||||
if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2)
|
||||
return -ENODEV;
|
||||
if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Any time a vcpu is run, vcpu_load is called which tries to grab the
|
||||
|
|
|
|||
Loading…
Reference in a new issue