[PATCH] ARM: KVM: Fix permission fault handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch fixes a very long standing bug in the KVM fault handling and
is basically a backport of the equivalent arm64 code.

The ARM ARM is quite explicit in saying the HPFAR cannot be trusted
for a permission fault, unless it is a Stage-1 page table walk.

The fact that it *seems* to work well enough on A15 is even more scary.
We may well be silently corrupting memory without even noticing (hint,
hint...). It is also quite possible that this bug would prevent KVM
from running on a CPU which caches TLBs covering VA to PA with a single
entry.

The fix is to detect aborts that are permission faults, and not stage-1
page table walk. We can then resolve the IPA, and store it just like the
HPFAR register. If the IPA cannot be resolved, it means another CPU is
playing with the page tables, and we simply restart the guest.

This also paves the way for lighter Icache invalidation, using the NX bit.

Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
---
 arch/arm/kvm/interrupts.S | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 5a09e89..38e9e4e 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -401,12 +401,47 @@ guest_trap:
 	mrc	p15, 4, r2, c6, c0, 0	@ HDFAR
 
 2:	str	r2, [r1, #VCPU_HxFAR]
-	mrc	p15, 4, r2, c6, c0, 4	@ HPFAR
+
+	/*
+	 * B3.13.5 Reporting exceptions taken to the Non-secure PL2 mode:
+	 *
+	 * Abort on the stage 2 translation for a memory access from a
+	 * Non-secure PL1 or PL0 mode:
+	 *
+	 * For any Access flag fault or Translation fault, and also for any
+	 * Permission fault on the stage 2 translation of a memory access
+	 * made as part of a translation table walk for a stage 1 translation,
+	 * the HPFAR holds the IPA that caused the fault. Otherwise, the HPFAR
+	 * is UNKNOWN.
+	 */
+
+	/* Check for permission fault, and S1PTW */
+	mrc	p15, 4, r1, c5, c2, 0	@ HSR
+	and	r0, r1, #HSR_FSC_TYPE
+	cmp	r0, #FSC_PERM
+	tsteq	r1, #7			@ S1PTW
+	mrcne	p15, 4, r2, c6, c0, 4	@ HPFAR
+	bne	3f
+
+	/* Resolve IPA using the xFAR */
+	mcr	p15, 0, r2, c7, c8, 1	@ ATS1CPW
+	isb
+	mrrc	p15, 0, r0, r1, c7	@ PAR
+	tst	r0, #1
+	bne	4f			@ Failed translation
+	ubfx	r2, r0, #12, #20
+	lsl	r2, r2, #4
+	orr	r2, r2, r1, lsl #24
+	
+3:	load_vcpu	r1
 	str	r2, [r1, #VCPU_HPFAR]
 
 1:	mov	r0, #ARM_EXCEPTION_HVC
 	b	__kvm_vcpu_return
 
+4:	pop	{r0, r1, r2}		@ Failed translation, return to guest
+	eret
+
 /*
  * If VFPv3 support is not available, then we will not switch the VFP
  * registers; however cp10 and cp11 accesses will still trap and fallback
-- 
1.7.12



_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux