* [PULL 01/19] KVM: arm/arm64: Don't enable/disable physical timer access on VHE
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
@ 2017-12-04 13:56 ` Christoffer Dall
2017-12-04 13:56 ` [PULL 02/19] KVM: arm/arm64: VGIC: extend !vgic_is_initialized guard Christoffer Dall
` (18 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 13:56 UTC (permalink / raw)
To: linux-arm-kernel
From: Christoffer Dall <christoffer.dall@linaro.org>
After the timer optimization rework we accidentally end up calling
physical timer enable/disable functions on VHE systems, which is neither
needed nor correct, since the CNTHCTL_EL2 register format is
different when HCR_EL2.E2H is set.
The CNTHCTL_EL2 is initialized when CPUs become online in
kvm_timer_init_vhe() and we don't have to call these functions on VHE
systems, which also allows us to inline the non-VHE functionality.
Reported-by: Jintack Lim <jintack@cs.columbia.edu>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
include/kvm/arm_arch_timer.h | 3 ---
virt/kvm/arm/arch_timer.c | 6 ------
virt/kvm/arm/hyp/timer-sr.c | 48 ++++++++++++++++++--------------------------
3 files changed, 20 insertions(+), 37 deletions(-)
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 01ee473517e2..6e45608b2399 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -93,7 +93,4 @@ void kvm_timer_init_vhe(void);
#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer)
#define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer)
-void enable_el1_phys_timer_access(void);
-void disable_el1_phys_timer_access(void);
-
#endif
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 4151250ce8da..190c99ed1b73 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -479,9 +479,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
vtimer_restore_state(vcpu);
- if (has_vhe())
- disable_el1_phys_timer_access();
-
/* Set the background timer for the physical timer emulation. */
phys_timer_emulate(vcpu);
}
@@ -510,9 +507,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
if (unlikely(!timer->enabled))
return;
- if (has_vhe())
- enable_el1_phys_timer_access();
-
vtimer_save_state(vcpu);
/*
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
index f39861639f08..f24404b3c8df 100644
--- a/virt/kvm/arm/hyp/timer-sr.c
+++ b/virt/kvm/arm/hyp/timer-sr.c
@@ -27,42 +27,34 @@ void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high)
write_sysreg(cntvoff, cntvoff_el2);
}
-void __hyp_text enable_el1_phys_timer_access(void)
-{
- u64 val;
-
- /* Allow physical timer/counter access for the host */
- val = read_sysreg(cnthctl_el2);
- val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
- write_sysreg(val, cnthctl_el2);
-}
-
-void __hyp_text disable_el1_phys_timer_access(void)
-{
- u64 val;
-
- /*
- * Disallow physical timer access for the guest
- * Physical counter access is allowed
- */
- val = read_sysreg(cnthctl_el2);
- val &= ~CNTHCTL_EL1PCEN;
- val |= CNTHCTL_EL1PCTEN;
- write_sysreg(val, cnthctl_el2);
-}
-
void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu)
{
/*
* We don't need to do this for VHE since the host kernel runs in EL2
* with HCR_EL2.TGE ==1, which makes those bits have no impact.
*/
- if (!has_vhe())
- enable_el1_phys_timer_access();
+ if (!has_vhe()) {
+ u64 val;
+
+ /* Allow physical timer/counter access for the host */
+ val = read_sysreg(cnthctl_el2);
+ val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
+ write_sysreg(val, cnthctl_el2);
+ }
}
void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu)
{
- if (!has_vhe())
- disable_el1_phys_timer_access();
+ if (!has_vhe()) {
+ u64 val;
+
+ /*
+ * Disallow physical timer access for the guest
+ * Physical counter access is allowed
+ */
+ val = read_sysreg(cnthctl_el2);
+ val &= ~CNTHCTL_EL1PCEN;
+ val |= CNTHCTL_EL1PCTEN;
+ write_sysreg(val, cnthctl_el2);
+ }
}
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 02/19] KVM: arm/arm64: VGIC: extend !vgic_is_initialized guard
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
2017-12-04 13:56 ` [PULL 01/19] KVM: arm/arm64: Don't enable/disable physical timer access on VHE Christoffer Dall
@ 2017-12-04 13:56 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 03/19] KVM: arm/arm64: vgic-irqfd: Fix MSI entry allocation Christoffer Dall
` (17 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 13:56 UTC (permalink / raw)
To: linux-arm-kernel
From: Andre Przywara <andre.przywara@arm.com>
Commit f39d16cbabf9 ("KVM: arm/arm64: Guard kvm_vgic_map_is_active against
!vgic_initialized") introduced a check whether the VGIC has been
initialized before accessing the spinlock and the VGIC data structure.
However the vgic_get_irq() call in the variable declaration sneaked
through the net, so lets make sure that this also gets called only after
we actually allocated the arrays this function accesses.
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index b168a328a9e0..786cce7bd2ec 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -823,13 +823,14 @@ void vgic_kick_vcpus(struct kvm *kvm)
bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid)
{
- struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
+ struct vgic_irq *irq;
bool map_is_active;
unsigned long flags;
if (!vgic_initialized(vcpu->kvm))
return false;
+ irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
spin_lock_irqsave(&irq->irq_lock, flags);
map_is_active = irq->hw && irq->active;
spin_unlock_irqrestore(&irq->irq_lock, flags);
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 03/19] KVM: arm/arm64: vgic-irqfd: Fix MSI entry allocation
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
2017-12-04 13:56 ` [PULL 01/19] KVM: arm/arm64: Don't enable/disable physical timer access on VHE Christoffer Dall
2017-12-04 13:56 ` [PULL 02/19] KVM: arm/arm64: VGIC: extend !vgic_is_initialized guard Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 04/19] KVM: arm/arm64: vgic: Preserve the revious read from the pending table Christoffer Dall
` (16 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
Using the size of the structure we're allocating is a good idea
and avoids any surprise... In this case, we're happilly confusing
kvm_kernel_irq_routing_entry and kvm_irq_routing_entry...
Fixes: 95b110ab9a09 ("KVM: arm/arm64: Enable irqchip routing")
Cc: <stable@vger.kernel.org> # 4.8
Reported-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-irqfd.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
index b7baf581611a..99e026d2dade 100644
--- a/virt/kvm/arm/vgic/vgic-irqfd.c
+++ b/virt/kvm/arm/vgic/vgic-irqfd.c
@@ -112,8 +112,7 @@ int kvm_vgic_setup_default_irq_routing(struct kvm *kvm)
u32 nr = dist->nr_spis;
int i, ret;
- entries = kcalloc(nr, sizeof(struct kvm_kernel_irq_routing_entry),
- GFP_KERNEL);
+ entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL);
if (!entries)
return -ENOMEM;
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 04/19] KVM: arm/arm64: vgic: Preserve the revious read from the pending table
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (2 preceding siblings ...)
2017-12-04 14:03 ` [PULL 03/19] KVM: arm/arm64: vgic-irqfd: Fix MSI entry allocation Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 05/19] KVM: arm/arm64: vgic-its: " Christoffer Dall
` (15 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
The current pending table parsing code assumes that we keep the
previous read of the pending bits, but keep that variable in
the current block, making sure it is discarded on each loop.
We end-up using whatever is on the stack. Who knows, it might
just be the right thing...
Fixes: 280771252c1ba ("KVM: arm64: vgic-v3: KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES")
Cc: <stable@vger.kernel.org> # 4.12
Reported-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-v3.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 2f05f732d3fd..f47e8481fa45 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -327,13 +327,13 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
int last_byte_offset = -1;
struct vgic_irq *irq;
int ret;
+ u8 val;
list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
int byte_offset, bit_nr;
struct kvm_vcpu *vcpu;
gpa_t pendbase, ptr;
bool stored;
- u8 val;
vcpu = irq->target_vcpu;
if (!vcpu)
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 05/19] KVM: arm/arm64: vgic-its: Preserve the revious read from the pending table
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (3 preceding siblings ...)
2017-12-04 14:03 ` [PULL 04/19] KVM: arm/arm64: vgic: Preserve the revious read from the pending table Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 06/19] KVM: arm/arm64: vgic-its: Check result of allocation before use Christoffer Dall
` (14 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
The current pending table parsing code assumes that we keep the
previous read of the pending bits, but keep that variable in
the current block, making sure it is discarded on each loop.
We end-up using whatever is on the stack. Who knows, it might
just be the right thing...
Fixes: 33d3bc9556a7d ("KVM: arm64: vgic-its: Read initial LPI pending table")
Cc: <stable@vger.kernel.org> # 4.8
Reported-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-its.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 1f761a9991e7..cb2d0a2dbe5a 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -421,6 +421,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
u32 *intids;
int nr_irqs, i;
unsigned long flags;
+ u8 pendmask;
nr_irqs = vgic_copy_lpi_list(vcpu, &intids);
if (nr_irqs < 0)
@@ -428,7 +429,6 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
for (i = 0; i < nr_irqs; i++) {
int byte_offset, bit_nr;
- u8 pendmask;
byte_offset = intids[i] / BITS_PER_BYTE;
bit_nr = intids[i] % BITS_PER_BYTE;
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 06/19] KVM: arm/arm64: vgic-its: Check result of allocation before use
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (4 preceding siblings ...)
2017-12-04 14:03 ` [PULL 05/19] KVM: arm/arm64: vgic-its: " Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 07/19] KVM: arm/arm64: vgic-v4: Only perform an unmap for valid vLPIs Christoffer Dall
` (13 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
We miss a test against NULL after allocation.
Fixes: 6d03a68f8054 ("KVM: arm64: vgic-its: Turn device_id validation into generic ID validation")
Cc: <stable@vger.kernel.org> # 4.8
Reported-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-its.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index cb2d0a2dbe5a..8e633bd9cc1e 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -821,6 +821,8 @@ static int vgic_its_alloc_collection(struct vgic_its *its,
return E_ITS_MAPC_COLLECTION_OOR;
collection = kzalloc(sizeof(*collection), GFP_KERNEL);
+ if (!collection)
+ return -ENOMEM;
collection->collection_id = coll_id;
collection->target_addr = COLLECTION_NOT_MAPPED;
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 07/19] KVM: arm/arm64: vgic-v4: Only perform an unmap for valid vLPIs
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (5 preceding siblings ...)
2017-12-04 14:03 ` [PULL 06/19] KVM: arm/arm64: vgic-its: Check result of allocation before use Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 08/19] arm64: KVM: fix VTTBR_BADDR_MASK BUG_ON off-by-one Christoffer Dall
` (12 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
Before performing an unmap, let's check that what we have was
really mapped the first place.
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-v4.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index 53c324aa44ef..4a37292855bc 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -337,8 +337,10 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq,
goto out;
WARN_ON(!(irq->hw && irq->host_irq == virq));
- irq->hw = false;
- ret = its_unmap_vlpi(virq);
+ if (irq->hw) {
+ irq->hw = false;
+ ret = its_unmap_vlpi(virq);
+ }
out:
mutex_unlock(&its->its_lock);
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 08/19] arm64: KVM: fix VTTBR_BADDR_MASK BUG_ON off-by-one
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (6 preceding siblings ...)
2017-12-04 14:03 ` [PULL 07/19] KVM: arm/arm64: vgic-v4: Only perform an unmap for valid vLPIs Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 09/19] arm: KVM: Fix " Christoffer Dall
` (11 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Kristina Martsenko <kristina.martsenko@arm.com>
VTTBR_BADDR_MASK is used to sanity check the size and alignment of the
VTTBR address. It seems to currently be off by one, thereby only
allowing up to 47-bit addresses (instead of 48-bit) and also
insufficiently checking the alignment. This patch fixes it.
As an example, with 4k pages, before this patch we have:
PHYS_MASK_SHIFT = 48
VTTBR_X = 37 - 24 = 13
VTTBR_BADDR_SHIFT = 13 - 1 = 12
VTTBR_BADDR_MASK = ((1 << 35) - 1) << 12 = 0x00007ffffffff000
Which is wrong, because the mask doesn't allow bit 47 of the VTTBR
address to be set, and only requires the address to be 12-bit (4k)
aligned, while it actually needs to be 13-bit (8k) aligned because we
concatenate two 4k tables.
With this patch, the mask becomes 0x0000ffffffffe000, which is what we
want.
Fixes: 0369f6a34b9f ("arm64: KVM: EL2 register definitions")
Cc: <stable@vger.kernel.org> # 3.11.x
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/include/asm/kvm_arm.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 7f069ff37f06..715d395ef45b 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -170,8 +170,7 @@
#define VTCR_EL2_FLAGS (VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN_FLAGS)
#define VTTBR_X (VTTBR_X_TGRAN_MAGIC - VTCR_EL2_T0SZ_IPA)
-#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_X)
#define VTTBR_VMID_SHIFT (UL(48))
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 09/19] arm: KVM: Fix VTTBR_BADDR_MASK BUG_ON off-by-one
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (7 preceding siblings ...)
2017-12-04 14:03 ` [PULL 08/19] arm64: KVM: fix VTTBR_BADDR_MASK BUG_ON off-by-one Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 10/19] KVM: arm/arm64: debug: Introduce helper for single-step Christoffer Dall
` (10 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
VTTBR_BADDR_MASK is used to sanity check the size and alignment of the
VTTBR address. It seems to currently be off by one, thereby only
allowing up to 39-bit addresses (instead of 40-bit) and also
insufficiently checking the alignment. This patch fixes it.
This patch is the 32bit pendent of Kristina's arm64 fix, and
she deserves the actual kudos for pinpointing that one.
Fixes: f7ed45be3ba52 ("KVM: ARM: World-switch implementation")
Cc: <stable@vger.kernel.org> # 3.9
Reported-by: Kristina Martsenko <kristina.martsenko@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/kvm_arm.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index c8781450905b..3ab8b3781bfe 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -161,8 +161,7 @@
#else
#define VTTBR_X (5 - KVM_T0SZ)
#endif
-#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_X)
#define VTTBR_VMID_SHIFT _AC(48, ULL)
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 10/19] KVM: arm/arm64: debug: Introduce helper for single-step
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (8 preceding siblings ...)
2017-12-04 14:03 ` [PULL 09/19] arm: KVM: Fix " Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 11/19] kvm: arm64: handle single-stepping trapped instructions Christoffer Dall
` (9 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Alex Benn?e <alex.bennee@linaro.org>
After emulating instructions we may want return to user-space to handle
single-step debugging. Introduce a helper function, which, if
single-step is enabled, sets the run structure for return and returns
true.
Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/kvm_host.h | 5 +++++
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/debug.c | 21 +++++++++++++++++++++
3 files changed, 27 insertions(+)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 242151ea6908..a9f7d3f47134 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,6 +285,11 @@ static inline void kvm_arm_init_debug(void) {}
static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
+static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
+ struct kvm_run *run)
+{
+ return false;
+}
int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 674912d7a571..ea6cb5b24258 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -370,6 +370,7 @@ void kvm_arm_init_debug(void);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index dbadfaf850a7..fa63b28c65e0 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -221,3 +221,24 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
}
}
}
+
+
+/*
+ * After successfully emulating an instruction, we might want to
+ * return to user space with a KVM_EXIT_DEBUG. We can only do this
+ * once the emulation is complete, though, so for userspace emulations
+ * we have to wait until we have re-entered KVM before calling this
+ * helper.
+ *
+ * Return true (and set exit_reason) to return to userspace or false
+ * if no further action is required.
+ */
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+ run->exit_reason = KVM_EXIT_DEBUG;
+ run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT;
+ return true;
+ }
+ return false;
+}
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 11/19] kvm: arm64: handle single-stepping trapped instructions
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (9 preceding siblings ...)
2017-12-04 14:03 ` [PULL 10/19] KVM: arm/arm64: debug: Introduce helper for single-step Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 12/19] kvm: arm64: handle single-step of userspace mmio instructions Christoffer Dall
` (8 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Alex Benn?e <alex.bennee@linaro.org>
If we are using guest debug to single-step the guest, we need to ensure
that we exit after emulating the instruction. This only affects
instructions completely emulated by the kernel. For instructions
emulated in userspace, we need to exit and return to complete the
emulation.
The kvm_arm_handle_step_debug() helper sets up the necessary exit
state if needed.
Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/handle_exit.c | 49 +++++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index b71247995469..029c28dd25e9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -186,6 +186,40 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
return arm_exit_handlers[hsr_ec];
}
+/*
+ * We may be single-stepping an emulated instruction. If the emulation
+ * has been completed in the kernel, we can return to userspace with a
+ * KVM_EXIT_DEBUG, otherwise userspace needs to complete its
+ * emulation first.
+ */
+static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ int handled;
+
+ /*
+ * See ARM ARM B1.14.1: "Hyp traps on instructions
+ * that fail their condition code check"
+ */
+ if (!kvm_condition_valid(vcpu)) {
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ handled = 1;
+ } else {
+ exit_handle_fn exit_handler;
+
+ exit_handler = kvm_get_exit_handler(vcpu);
+ handled = exit_handler(vcpu, run);
+ }
+
+ /*
+ * kvm_arm_handle_step_debug() sets the exit_reason on the kvm_run
+ * structure if we need to return to userspace.
+ */
+ if (handled > 0 && kvm_arm_handle_step_debug(vcpu, run))
+ handled = 0;
+
+ return handled;
+}
+
/*
* Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
* proper exit to userspace.
@@ -193,8 +227,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index)
{
- exit_handle_fn exit_handler;
-
if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
@@ -222,18 +254,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_inject_vabt(vcpu);
return 1;
case ARM_EXCEPTION_TRAP:
- /*
- * See ARM ARM B1.14.1: "Hyp traps on instructions
- * that fail their condition code check"
- */
- if (!kvm_condition_valid(vcpu)) {
- kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
- return 1;
- }
-
- exit_handler = kvm_get_exit_handler(vcpu);
-
- return exit_handler(vcpu, run);
+ return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
/*
* EL2 has been reset to the hyp-stub. This happens when a guest
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 12/19] kvm: arm64: handle single-step of userspace mmio instructions
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (10 preceding siblings ...)
2017-12-04 14:03 ` [PULL 11/19] kvm: arm64: handle single-stepping trapped instructions Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 13/19] kvm: arm64: handle single-step during SError exceptions Christoffer Dall
` (7 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Alex Benn?e <alex.bennee@linaro.org>
The system state of KVM when using userspace emulation is not complete
until we return into KVM_RUN. To handle mmio related updates we wait
until they have been committed and then schedule our KVM_EXIT_DEBUG.
The kvm_arm_handle_step_debug() helper tells us if we need to return
and sets up the exit_reason for us.
Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index a6524ff27de4..322c570d211e 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -628,6 +628,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = kvm_handle_mmio_return(vcpu, vcpu->run);
if (ret)
return ret;
+ if (kvm_arm_handle_step_debug(vcpu, vcpu->run))
+ return 0;
+
}
if (run->immediate_exit)
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 13/19] kvm: arm64: handle single-step during SError exceptions
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (11 preceding siblings ...)
2017-12-04 14:03 ` [PULL 12/19] kvm: arm64: handle single-step of userspace mmio instructions Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 14/19] kvm: arm64: handle single-step of hyp emulated mmio instructions Christoffer Dall
` (6 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Alex Benn?e <alex.bennee@linaro.org>
When an SError arrives during single-step both the SError and debug
exceptions may be pending when the step is completed, and the
architecture doesn't define the ordering of the two. This means that we
can observe en SError even though we've just completed a step, without
receiving a debug exception. In that case the DBG_SPSR_SS bit will have
flipped as the instruction executed. After handling the abort in
handle_exit() we test to see if the bit is clear and we were
single-stepping before deciding if we need to exit to user space.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/handle_exit.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 029c28dd25e9..304203fa9e33 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,6 +28,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_psci.h>
+#include <asm/debug-monitors.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
@@ -252,7 +253,12 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 1;
case ARM_EXCEPTION_EL1_SERROR:
kvm_inject_vabt(vcpu);
- return 1;
+ /* We may still need to return for single-step */
+ if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+ && kvm_arm_handle_step_debug(vcpu, run))
+ return 0;
+ else
+ return 1;
case ARM_EXCEPTION_TRAP:
return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 14/19] kvm: arm64: handle single-step of hyp emulated mmio instructions
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (12 preceding siblings ...)
2017-12-04 14:03 ` [PULL 13/19] kvm: arm64: handle single-step during SError exceptions Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 15/19] KVM: arm/arm64: Avoid attempting to load timer vgic state without a vgic Christoffer Dall
` (5 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Alex Benn?e <alex.bennee@linaro.org>
There is a fast-path of MMIO emulation inside hyp mode. The handling
of single-step is broadly the same as kvm_arm_handle_step_debug()
except we just setup ESR/HSR so handle_exit() does the correct thing
as we exit.
For the case of an emulated illegal access causing an SError we will
exit via the ARM_EXCEPTION_EL1_SERROR path in handle_exit(). We behave
as we would during a real SError and clear the DBG_SPSR_SS bit for the
emulated instruction.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Alex Benn?e <alex.bennee@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/hyp/switch.c | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 525c01f48867..f7c651f3a8c0 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -22,6 +22,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
#include <asm/fpsimd.h>
+#include <asm/debug-monitors.h>
static bool __hyp_text __fpsimd_enabled_nvhe(void)
{
@@ -269,7 +270,11 @@ static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
return true;
}
-static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
+/* Skip an instruction which has been emulated. Returns true if
+ * execution can continue or false if we need to exit hyp mode because
+ * single-step was in effect.
+ */
+static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
{
*vcpu_pc(vcpu) = read_sysreg_el2(elr);
@@ -282,6 +287,14 @@ static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
}
write_sysreg_el2(*vcpu_pc(vcpu), elr);
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+ vcpu->arch.fault.esr_el2 =
+ (ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT) | 0x22;
+ return false;
+ } else {
+ return true;
+ }
}
int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
@@ -342,13 +355,21 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v2_perform_cpuif_access(vcpu);
if (ret == 1) {
- __skip_instr(vcpu);
- goto again;
+ if (__skip_instr(vcpu))
+ goto again;
+ else
+ exit_code = ARM_EXCEPTION_TRAP;
}
if (ret == -1) {
- /* Promote an illegal access to an SError */
- __skip_instr(vcpu);
+ /* Promote an illegal access to an
+ * SError. If we would be returning
+ * due to single-step clear the SS
+ * bit so handle_exit knows what to
+ * do after dealing with the error.
+ */
+ if (!__skip_instr(vcpu))
+ *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
exit_code = ARM_EXCEPTION_EL1_SERROR;
}
@@ -363,8 +384,10 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v3_perform_cpuif_access(vcpu);
if (ret == 1) {
- __skip_instr(vcpu);
- goto again;
+ if (__skip_instr(vcpu))
+ goto again;
+ else
+ exit_code = ARM_EXCEPTION_TRAP;
}
/* 0 falls through to be handled out of EL2 */
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 15/19] KVM: arm/arm64: Avoid attempting to load timer vgic state without a vgic
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (13 preceding siblings ...)
2017-12-04 14:03 ` [PULL 14/19] kvm: arm64: handle single-step of hyp emulated mmio instructions Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 16/19] kvm: arm: don't treat unavailable HYP mode as an error Christoffer Dall
` (4 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Christoffer Dall <christoffer.dall@linaro.org>
The timer optimization patches inadvertendly changed the logic to always
load the timer state as if we have a vgic, even if we don't have a vgic.
Fix this by doing the usual irqchip_in_kernel() check and call the
appropriate load function.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arch_timer.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 190c99ed1b73..f9555b1e7f15 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -835,7 +835,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
no_vgic:
preempt_disable();
timer->enabled = 1;
- kvm_timer_vcpu_load_vgic(vcpu);
+ if (!irqchip_in_kernel(vcpu->kvm))
+ kvm_timer_vcpu_load_user(vcpu);
+ else
+ kvm_timer_vcpu_load_vgic(vcpu);
preempt_enable();
return 0;
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 16/19] kvm: arm: don't treat unavailable HYP mode as an error
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (14 preceding siblings ...)
2017-12-04 14:03 ` [PULL 15/19] KVM: arm/arm64: Avoid attempting to load timer vgic state without a vgic Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 17/19] KVM: arm/arm64: Fix spinlock acquisition in vgic_set_owner Christoffer Dall
` (3 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Since it is perfectly legal to run the kernel at EL1, it is not
actually an error if HYP mode is not available when attempting to
initialize KVM, given that KVM support cannot be built as a module.
So demote the kvm_err() to kvm_info(), which prevents the error from
appearing on an otherwise 'quiet' console.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 322c570d211e..ca65d06b38a8 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1507,7 +1507,7 @@ int kvm_arch_init(void *opaque)
bool in_hyp_mode;
if (!is_hyp_mode_available()) {
- kvm_err("HYP mode not available\n");
+ kvm_info("HYP mode not available\n");
return -ENODEV;
}
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 17/19] KVM: arm/arm64: Fix spinlock acquisition in vgic_set_owner
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (15 preceding siblings ...)
2017-12-04 14:03 ` [PULL 16/19] kvm: arm: don't treat unavailable HYP mode as an error Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 18/19] KVM: arm/arm64: kvm_arch_destroy_vm cleanups Christoffer Dall
` (2 subsequent siblings)
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
vgic_set_owner acquires the irq lock without disabling interrupts,
resulting in a lockdep splat (an interrupt could fire and result
in the same lock being taken if the same virtual irq is to be
injected).
In practice, it is almost impossible to trigger this bug, but
better safe than sorry. Convert the lock acquisition to a
spin_lock_irqsave() and keep lockdep happy.
Reported-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 786cce7bd2ec..ecb8e25f5fe5 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -492,6 +492,7 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner)
{
struct vgic_irq *irq;
+ unsigned long flags;
int ret = 0;
if (!vgic_initialized(vcpu->kvm))
@@ -502,12 +503,12 @@ int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner)
return -EINVAL;
irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
- spin_lock(&irq->irq_lock);
+ spin_lock_irqsave(&irq->irq_lock, flags);
if (irq->owner && irq->owner != owner)
ret = -EEXIST;
else
irq->owner = owner;
- spin_unlock(&irq->irq_lock);
+ spin_unlock_irqrestore(&irq->irq_lock, flags);
return ret;
}
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 18/19] KVM: arm/arm64: kvm_arch_destroy_vm cleanups
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (16 preceding siblings ...)
2017-12-04 14:03 ` [PULL 17/19] KVM: arm/arm64: Fix spinlock acquisition in vgic_set_owner Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-04 14:03 ` [PULL 19/19] KVM: arm/arm64: Fix broken GICH_ELRSR big endian conversion Christoffer Dall
2017-12-05 17:59 ` [PULL 00/19] KVM/ARM Fixes for v4.15 Radim Krčmář
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Andrew Jones <drjones@redhat.com>
kvm_vgic_vcpu_destroy already gets called from kvm_vgic_destroy for
each vcpu, so we don't have to call it from kvm_arch_vcpu_free.
Additionally the other architectures set kvm->online_vcpus to zero
after freeing them. We might as well do that for ARM too.
Signed-off-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index ca65d06b38a8..675844c2174a 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -188,6 +188,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kvm->vcpus[i] = NULL;
}
}
+ atomic_set(&kvm->online_vcpus, 0);
}
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
@@ -296,7 +297,6 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
{
kvm_mmu_free_memory_caches(vcpu);
kvm_timer_vcpu_terminate(vcpu);
- kvm_vgic_vcpu_destroy(vcpu);
kvm_pmu_vcpu_destroy(vcpu);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu);
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 19/19] KVM: arm/arm64: Fix broken GICH_ELRSR big endian conversion
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (17 preceding siblings ...)
2017-12-04 14:03 ` [PULL 18/19] KVM: arm/arm64: kvm_arch_destroy_vm cleanups Christoffer Dall
@ 2017-12-04 14:03 ` Christoffer Dall
2017-12-05 17:59 ` [PULL 00/19] KVM/ARM Fixes for v4.15 Radim Krčmář
19 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2017-12-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
From: Christoffer Dall <christoffer.dall@linaro.org>
We are incorrectly rearranging 32-bit words inside a 64-bit typed value
for big endian systems, which would result in never marking a virtual
interrupt as inactive on big endian systems (assuming 32 or fewer LRs on
the hardware). Fix this by not doing any word order manipulation for
the typed values.
Cc: <stable@vger.kernel.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/hyp/vgic-v2-sr.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index a3f18d362366..d7fd46fe9efb 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -34,11 +34,7 @@ static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base)
else
elrsr1 = 0;
-#ifdef CONFIG_CPU_BIG_ENDIAN
- cpu_if->vgic_elrsr = ((u64)elrsr0 << 32) | elrsr1;
-#else
cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0;
-#endif
}
static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
--
2.14.2
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PULL 00/19] KVM/ARM Fixes for v4.15
2017-12-04 13:56 [PULL 00/19] KVM/ARM Fixes for v4.15 Christoffer Dall
` (18 preceding siblings ...)
2017-12-04 14:03 ` [PULL 19/19] KVM: arm/arm64: Fix broken GICH_ELRSR big endian conversion Christoffer Dall
@ 2017-12-05 17:59 ` Radim Krčmář
19 siblings, 0 replies; 23+ messages in thread
From: Radim Krčmář @ 2017-12-05 17:59 UTC (permalink / raw)
To: linux-arm-kernel
2017-12-04 14:56+0100, Christoffer Dall:
> From: Christoffer Dall <christoffer.dall@linaro.org>
>
> Hi Paolo and Radim,
>
> Here's the first round of fixes for KVM/ARM for v4.15. This is a fairly large
> set of fixes, partially because we spotted a handful of issues from running the
> SMATCH static analysis on the code (thanks to AKASHI Takahiro).
>
> In more details, this pull request fixes:
> - A number of issues in the vgic discovered using SMATCH
> - A bit one-off calculation in out stage base address mask (32-bit and
> 64-bit)
> - Fixes to single-step debugging instructions that trap for other
> reasons such as MMMIO aborts
> - Printing unavailable hyp mode as error
> - Potential spinlock deadlock in the vgic
> - Avoid calling vgic vcpu free more than once
> - Broken bit calculation for big endian systems
Pulled, thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread