Selaa lähdekoodia

KVM: PPC: E500: Add dcbtls emulation

The dcbtls instruction is able to lock data inside the L1 cache.

We don't want to give the guest actual access to hardware cache locks,
as that could influence other VMs on the same system. But we can tell
the guest that its locking attempt failed.

By implementing the instruction we at least don't give the guest a
program exception which it definitely does not expect.

Signed-off-by: Alexander Graf <agraf@suse.de>
Alexander Graf 11 vuotta sitten
vanhempi
commit
8f20a3ab27
2 muutettua tiedostoa jossa 15 lisäystä ja 0 poistoa
  1. 1 0
      arch/powerpc/include/asm/reg_booke.h
  2. 14 0
      arch/powerpc/kvm/e500_emulate.c

+ 1 - 0
arch/powerpc/include/asm/reg_booke.h

@@ -583,6 +583,7 @@
 
 
 /* Bit definitions for L1CSR0. */
 /* Bit definitions for L1CSR0. */
 #define L1CSR0_CPE	0x00010000	/* Data Cache Parity Enable */
 #define L1CSR0_CPE	0x00010000	/* Data Cache Parity Enable */
+#define L1CSR0_CUL	0x00000400	/* Data Cache Unable to Lock */
 #define L1CSR0_CLFC	0x00000100	/* Cache Lock Bits Flash Clear */
 #define L1CSR0_CLFC	0x00000100	/* Cache Lock Bits Flash Clear */
 #define L1CSR0_DCFI	0x00000002	/* Data Cache Flash Invalidate */
 #define L1CSR0_DCFI	0x00000002	/* Data Cache Flash Invalidate */
 #define L1CSR0_CFI	0x00000002	/* Cache Flash Invalidate */
 #define L1CSR0_CFI	0x00000002	/* Cache Flash Invalidate */

+ 14 - 0
arch/powerpc/kvm/e500_emulate.c

@@ -19,6 +19,7 @@
 #include "booke.h"
 #include "booke.h"
 #include "e500.h"
 #include "e500.h"
 
 
+#define XOP_DCBTLS  166
 #define XOP_MSGSND  206
 #define XOP_MSGSND  206
 #define XOP_MSGCLR  238
 #define XOP_MSGCLR  238
 #define XOP_TLBIVAX 786
 #define XOP_TLBIVAX 786
@@ -103,6 +104,15 @@ static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	return emulated;
 	return emulated;
 }
 }
 
 
+static int kvmppc_e500_emul_dcbtls(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	/* Always fail to lock the cache */
+	vcpu_e500->l1csr0 |= L1CSR0_CUL;
+	return EMULATE_DONE;
+}
+
 int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
 int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
 				unsigned int inst, int *advance)
 				unsigned int inst, int *advance)
 {
 {
@@ -116,6 +126,10 @@ int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	case 31:
 	case 31:
 		switch (get_xop(inst)) {
 		switch (get_xop(inst)) {
 
 
+		case XOP_DCBTLS:
+			emulated = kvmppc_e500_emul_dcbtls(vcpu);
+			break;
+
 #ifdef CONFIG_KVM_E500MC
 #ifdef CONFIG_KVM_E500MC
 		case XOP_MSGSND:
 		case XOP_MSGSND:
 			emulated = kvmppc_e500_emul_msgsnd(vcpu, rb);
 			emulated = kvmppc_e500_emul_msgsnd(vcpu, rb);