All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes
@ 2016-06-09  9:50 James Hogan
  2016-06-09  9:50 ` [PATCH 1/4] MIPS: KVM: Fix modular KVM under QEMU James Hogan
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: James Hogan @ 2016-06-09  9:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: James Hogan, Radim Krčmář,
	Ralf Baechle, kvm, linux-mips, stable

These patches fix a couple of issues I recently spotted when running KVM
under QEMU (i.e. the host MIPS kernel is running under QEMU on a PC).

Patches 1-2: Fix modular KVM broken by QEMU TLB optimisation (Patch 1
marked for stable).

Patches 3-4: Fix cache instruction emulation, exposed by having dynamic
translation of emulated instructions accidentally turned off.

James Hogan (4):
  MIPS: KVM: Fix modular KVM under QEMU
  MIPS: KVM: Include bit 31 in segment matches
  MIPS: KVM: Don't unwind PC when emulating CACHE
  MIPS: KVM: Fix CACHE triggered exception emulation

 arch/mips/include/asm/kvm_host.h |  3 ++-
 arch/mips/kvm/emulate.c          | 21 ++++++++++++++-------
 arch/mips/kvm/interrupt.h        |  1 +
 arch/mips/kvm/locore.S           |  1 +
 arch/mips/kvm/mips.c             | 11 ++++++++++-
 5 files changed, 28 insertions(+), 9 deletions(-)

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: stable@vger.kernel.org
-- 
2.4.10


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] MIPS: KVM: Fix modular KVM under QEMU
  2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
@ 2016-06-09  9:50 ` James Hogan
  2016-06-09  9:50 ` [PATCH 2/4] MIPS: KVM: Include bit 31 in segment matches James Hogan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: James Hogan @ 2016-06-09  9:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: James Hogan, Radim Krčmář,
	Ralf Baechle, kvm, linux-mips, stable

Copy __kvm_mips_vcpu_run() into unmapped memory, so that we can never
get a TLB refill exception in it when KVM is built as a module.

This was observed to happen with the host MIPS kernel running under
QEMU, due to a not entirely transparent optimisation in the QEMU TLB
handling where TLB entries replaced with TLBWR are copied to a separate
part of the TLB array. Code in those pages continue to be executable,
but those mappings persist only until the next ASID switch, even if they
are marked global.

An ASID switch happens in __kvm_mips_vcpu_run() at exception level after
switching to the guest exception base. Subsequent TLB mapped kernel
instructions just prior to switching to the guest trigger a TLB refill
exception, which enters the guest exception handlers without updating
EPC. This appears as a guest triggered TLB refill on a host kernel
mapped (host KSeg2) address, which is not handled correctly as user
(guest) mode accesses to kernel (host) segments always generate address
error exceptions.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: <stable@vger.kernel.org> # 3.10.x-
---
 arch/mips/include/asm/kvm_host.h |  1 +
 arch/mips/kvm/interrupt.h        |  1 +
 arch/mips/kvm/locore.S           |  1 +
 arch/mips/kvm/mips.c             | 11 ++++++++++-
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 6733ac575da4..2d5bb133d11a 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -338,6 +338,7 @@ struct kvm_mips_tlb {
 #define KVM_MIPS_GUEST_TLB_SIZE	64
 struct kvm_vcpu_arch {
 	void *host_ebase, *guest_ebase;
+	int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	unsigned long host_stack;
 	unsigned long host_gp;
 
diff --git a/arch/mips/kvm/interrupt.h b/arch/mips/kvm/interrupt.h
index 4ab4bdfad703..2143884709e4 100644
--- a/arch/mips/kvm/interrupt.h
+++ b/arch/mips/kvm/interrupt.h
@@ -28,6 +28,7 @@
 #define MIPS_EXC_MAX                12
 /* XXXSL More to follow */
 
+extern char __kvm_mips_vcpu_run_end[];
 extern char mips32_exception[], mips32_exceptionEnd[];
 extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
 
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
index 3ef03009de5f..828fcfc1cd7f 100644
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -202,6 +202,7 @@ FEXPORT(__kvm_mips_load_k0k1)
 
 	/* Jump to guest */
 	eret
+EXPORT(__kvm_mips_vcpu_run_end)
 
 VECTOR(MIPSX(exception), unknown)
 /* Find out what mode we came from and jump to the proper handler. */
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index dc052fb5c7a2..44da5259f390 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -315,6 +315,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 	memcpy(gebase + offset, mips32_GuestException,
 	       mips32_GuestExceptionEnd - mips32_GuestException);
 
+#ifdef MODULE
+	offset += mips32_GuestExceptionEnd - mips32_GuestException;
+	memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
+	       __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
+	vcpu->arch.vcpu_run = gebase + offset;
+#else
+	vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
+#endif
+
 	/* Invalidate the icache for these ranges */
 	local_flush_icache_range((unsigned long)gebase,
 				(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
@@ -404,7 +413,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	/* Disable hardware page table walking while in guest */
 	htw_stop();
 
-	r = __kvm_mips_vcpu_run(run, vcpu);
+	r = vcpu->arch.vcpu_run(run, vcpu);
 
 	/* Re-enable HTW before enabling interrupts */
 	htw_start();
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] MIPS: KVM: Include bit 31 in segment matches
  2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
  2016-06-09  9:50 ` [PATCH 1/4] MIPS: KVM: Fix modular KVM under QEMU James Hogan
@ 2016-06-09  9:50 ` James Hogan
  2016-06-09  9:50 ` [PATCH 3/4] MIPS: KVM: Don't unwind PC when emulating CACHE James Hogan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: James Hogan @ 2016-06-09  9:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: James Hogan, Radim Krčmář, Ralf Baechle, kvm, linux-mips

When faulting guest addresses are matched against guest segments with
the KVM_GUEST_KSEGX() macro, change the mask to 0xe0000000 so as to
include bit 31.

This is mainly for safety's sake, as it prevents a rogue BadVAddr in the
host kseg2/kseg3 segments (e.g. 0xC*******) after a TLB exception from
matching the guest kseg0 segment (e.g. 0x4*******), triggering an
internal KVM error instead of allowing the corresponding guest kseg0
page to be mapped into the host vmalloc space.

Such a rogue BadVAddr was observed to happen with the host MIPS kernel
running under QEMU with KVM built as a module, due to a not entirely
transparent optimisation in the QEMU TLB handling. This has already been
worked around properly in a previous commit.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
---
 arch/mips/include/asm/kvm_host.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 2d5bb133d11a..36a391d289aa 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -74,7 +74,7 @@
 #define KVM_GUEST_KUSEG			0x00000000UL
 #define KVM_GUEST_KSEG0			0x40000000UL
 #define KVM_GUEST_KSEG23		0x60000000UL
-#define KVM_GUEST_KSEGX(a)		((_ACAST32_(a)) & 0x60000000)
+#define KVM_GUEST_KSEGX(a)		((_ACAST32_(a)) & 0xe0000000)
 #define KVM_GUEST_CPHYSADDR(a)		((_ACAST32_(a)) & 0x1fffffff)
 
 #define KVM_GUEST_CKSEG0ADDR(a)		(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0)
-- 
2.4.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] MIPS: KVM: Don't unwind PC when emulating CACHE
  2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
  2016-06-09  9:50 ` [PATCH 1/4] MIPS: KVM: Fix modular KVM under QEMU James Hogan
  2016-06-09  9:50 ` [PATCH 2/4] MIPS: KVM: Include bit 31 in segment matches James Hogan
@ 2016-06-09  9:50 ` James Hogan
  2016-06-09  9:50 ` [PATCH 4/4] MIPS: KVM: Fix CACHE triggered exception emulation James Hogan
  2016-06-12 18:45 ` [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes Paolo Bonzini
  4 siblings, 0 replies; 7+ messages in thread
From: James Hogan @ 2016-06-09  9:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: James Hogan, Radim Krčmář, Ralf Baechle, kvm, linux-mips

When a CACHE instruction is emulated by kvm_mips_emulate_cache(), the PC
is first updated to point to the next instruction, and afterwards it
falls through the "dont_update_pc" label, which rewinds the PC back to
its original address.

This works when dynamic translation of emulated instructions is enabled,
since the CACHE instruction is replaced with a SYNCI which works without
trapping, however when dynamic translation is disabled the guest hangs
on CACHE instructions as they always trap and are never stepped over.

Roughly swap the meanings of the "done" and "dont_update_pc" to match
kvm_mips_emulate_CP0(), so that "done" will roll back the PC on failure,
and "dont_update_pc" won't change PC at all (for the sake of exceptions
that have already modified the PC).

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
---
 arch/mips/kvm/emulate.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 396df6eb0a12..52bec0fe2fbb 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1666,7 +1666,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 			cache, op, base, arch->gprs[base], offset);
 		er = EMULATE_FAIL;
 		preempt_enable();
-		goto dont_update_pc;
+		goto done;
 
 	}
 
@@ -1694,16 +1694,20 @@ skip_fault:
 		kvm_err("NO-OP CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
 			cache, op, base, arch->gprs[base], offset);
 		er = EMULATE_FAIL;
-		preempt_enable();
-		goto dont_update_pc;
 	}
 
 	preempt_enable();
-
-dont_update_pc:
-	/* Rollback PC */
-	vcpu->arch.pc = curr_pc;
 done:
+	/* Rollback PC only if emulation was unsuccessful */
+	if (er == EMULATE_FAIL)
+		vcpu->arch.pc = curr_pc;
+
+dont_update_pc:
+	/*
+	 * This is for exceptions whose emulation updates the PC, so do not
+	 * overwrite the PC under any circumstances
+	 */
+
 	return er;
 }
 
-- 
2.4.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] MIPS: KVM: Fix CACHE triggered exception emulation
  2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
                   ` (2 preceding siblings ...)
  2016-06-09  9:50 ` [PATCH 3/4] MIPS: KVM: Don't unwind PC when emulating CACHE James Hogan
@ 2016-06-09  9:50 ` James Hogan
  2016-06-12 18:45 ` [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes Paolo Bonzini
  4 siblings, 0 replies; 7+ messages in thread
From: James Hogan @ 2016-06-09  9:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: James Hogan, Radim Krčmář, Ralf Baechle, kvm, linux-mips

When emulating TLB miss / invalid exceptions during CACHE instruction
emulation, be sure to set up the correct PC and host_cp0_badvaddr state
for the kvm_mips_emlulate_tlb*_ld() function to pick up for guest EPC
and BadVAddr.

PC needs to be rewound otherwise the guest EPC will end up pointing at
the next instruction after the faulting CACHE instruction.

host_cp0_badvaddr must be set because guest CACHE instructions trap with
a Coprocessor Unusable exception, which doesn't update the host BadVAddr
as a TLB exception would.

This doesn't tend to get hit when dynamic translation of emulated
instructions is enabled, since only the first execution of each CACHE
instruction actually goes through this code path, with subsequent
executions hitting the SYNCI instruction that it gets replaced with.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
---
 arch/mips/kvm/emulate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 52bec0fe2fbb..645c8a1982a7 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1636,6 +1636,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 		if (index < 0) {
 			vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK);
 			vcpu->arch.host_cp0_badvaddr = va;
+			vcpu->arch.pc = curr_pc;
 			er = kvm_mips_emulate_tlbmiss_ld(cause, NULL, run,
 							 vcpu);
 			preempt_enable();
@@ -1647,6 +1648,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 			 * invalid exception to the guest
 			 */
 			if (!TLB_IS_VALID(*tlb, va)) {
+				vcpu->arch.host_cp0_badvaddr = va;
+				vcpu->arch.pc = curr_pc;
 				er = kvm_mips_emulate_tlbinv_ld(cause, NULL,
 								run, vcpu);
 				preempt_enable();
-- 
2.4.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes
  2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
                   ` (3 preceding siblings ...)
  2016-06-09  9:50 ` [PATCH 4/4] MIPS: KVM: Fix CACHE triggered exception emulation James Hogan
@ 2016-06-12 18:45 ` Paolo Bonzini
  2016-06-14  9:03   ` Paolo Bonzini
  4 siblings, 1 reply; 7+ messages in thread
From: Paolo Bonzini @ 2016-06-12 18:45 UTC (permalink / raw)
  To: James Hogan
  Cc: Radim Krčmář, Ralf Baechle, kvm, linux-mips, stable



On 09/06/2016 11:50, James Hogan wrote:
> These patches fix a couple of issues I recently spotted when running KVM
> under QEMU (i.e. the host MIPS kernel is running under QEMU on a PC).
> 
> Patches 1-2: Fix modular KVM broken by QEMU TLB optimisation (Patch 1
> marked for stable).
> 
> Patches 3-4: Fix cache instruction emulation, exposed by having dynamic
> translation of emulated instructions accidentally turned off.
> 
> James Hogan (4):
>   MIPS: KVM: Fix modular KVM under QEMU
>   MIPS: KVM: Include bit 31 in segment matches
>   MIPS: KVM: Don't unwind PC when emulating CACHE
>   MIPS: KVM: Fix CACHE triggered exception emulation
> 
>  arch/mips/include/asm/kvm_host.h |  3 ++-
>  arch/mips/kvm/emulate.c          | 21 ++++++++++++++-------
>  arch/mips/kvm/interrupt.h        |  1 +
>  arch/mips/kvm/locore.S           |  1 +
>  arch/mips/kvm/mips.c             | 11 ++++++++++-
>  5 files changed, 28 insertions(+), 9 deletions(-)
> 
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Radim Krčmář <rkrcmar@redhat.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: kvm@vger.kernel.org
> Cc: linux-mips@linux-mips.org
> Cc: stable@vger.kernel.org
> 

Queued for kvm/master.

Paolo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes
  2016-06-12 18:45 ` [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes Paolo Bonzini
@ 2016-06-14  9:03   ` Paolo Bonzini
  0 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2016-06-14  9:03 UTC (permalink / raw)
  To: James Hogan
  Cc: Radim Krčmář, Ralf Baechle, kvm, linux-mips, stable



On 12/06/2016 20:45, Paolo Bonzini wrote:
> 
> 
> On 09/06/2016 11:50, James Hogan wrote:
>> These patches fix a couple of issues I recently spotted when running KVM
>> under QEMU (i.e. the host MIPS kernel is running under QEMU on a PC).
>>
>> Patches 1-2: Fix modular KVM broken by QEMU TLB optimisation (Patch 1
>> marked for stable).
>>
>> Patches 3-4: Fix cache instruction emulation, exposed by having dynamic
>> translation of emulated instructions accidentally turned off.
>>
>> James Hogan (4):
>>   MIPS: KVM: Fix modular KVM under QEMU
>>   MIPS: KVM: Include bit 31 in segment matches
>>   MIPS: KVM: Don't unwind PC when emulating CACHE
>>   MIPS: KVM: Fix CACHE triggered exception emulation
>>
>>  arch/mips/include/asm/kvm_host.h |  3 ++-
>>  arch/mips/kvm/emulate.c          | 21 ++++++++++++++-------
>>  arch/mips/kvm/interrupt.h        |  1 +
>>  arch/mips/kvm/locore.S           |  1 +
>>  arch/mips/kvm/mips.c             | 11 ++++++++++-
>>  5 files changed, 28 insertions(+), 9 deletions(-)
>>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: Radim Krčmář <rkrcmar@redhat.com>
>> Cc: Ralf Baechle <ralf@linux-mips.org>
>> Cc: kvm@vger.kernel.org
>> Cc: linux-mips@linux-mips.org
>> Cc: stable@vger.kernel.org
>>
> 
> Queued for kvm/master.

... and kvm/next too, since your patches conflict with this one.

Paolo

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-06-14  9:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-09  9:50 [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes James Hogan
2016-06-09  9:50 ` [PATCH 1/4] MIPS: KVM: Fix modular KVM under QEMU James Hogan
2016-06-09  9:50 ` [PATCH 2/4] MIPS: KVM: Include bit 31 in segment matches James Hogan
2016-06-09  9:50 ` [PATCH 3/4] MIPS: KVM: Don't unwind PC when emulating CACHE James Hogan
2016-06-09  9:50 ` [PATCH 4/4] MIPS: KVM: Fix CACHE triggered exception emulation James Hogan
2016-06-12 18:45 ` [PATCH 0/4] MIPS: KVM: Module + non dynamic translating fixes Paolo Bonzini
2016-06-14  9:03   ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.