All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core
@ 2013-03-26 22:05 ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Enable basic support for Freescale e6500 core, adding MAV 2.0 support.
Validated on T4240QDS platfrom. Altivec, Multithreading and HW Tablewalk
are not addressed by this patchset.

Mihai Caraman (7):
  KVM: PPC: e500: Expose MMU registers via ONE_REG
  KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
  KVM: PPC: e500: Add support for TLBnPS registers
  KVM: PPC: e500: Add support for EPTCFG register
  KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  KVM: PPC: e500mc: Enable e6500 cores
  KVM: PPC: e500: Add e6500 core to Kconfig description

 Documentation/virtual/kvm/api.txt   |   16 +++
 arch/powerpc/include/asm/kvm_host.h |    2 +
 arch/powerpc/include/uapi/asm/kvm.h |   22 ++++
 arch/powerpc/kvm/44x.c              |   12 +++
 arch/powerpc/kvm/Kconfig            |    6 +-
 arch/powerpc/kvm/booke.c            |   83 ++++++++++-------
 arch/powerpc/kvm/e500.c             |   14 +++
 arch/powerpc/kvm/e500.h             |   25 +++++
 arch/powerpc/kvm/e500_emulate.c     |   19 ++++
 arch/powerpc/kvm/e500_mmu.c         |  181 ++++++++++++++++++++++++++++++----
 arch/powerpc/kvm/e500mc.c           |   16 +++
 11 files changed, 337 insertions(+), 59 deletions(-)

-- 
1.7.4.1

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

* [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core
@ 2013-03-26 22:05 ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Enable basic support for Freescale e6500 core, adding MAV 2.0 support.
Validated on T4240QDS platfrom. Altivec, Multithreading and HW Tablewalk
are not addressed by this patchset.

Mihai Caraman (7):
  KVM: PPC: e500: Expose MMU registers via ONE_REG
  KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
  KVM: PPC: e500: Add support for TLBnPS registers
  KVM: PPC: e500: Add support for EPTCFG register
  KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  KVM: PPC: e500mc: Enable e6500 cores
  KVM: PPC: e500: Add e6500 core to Kconfig description

 Documentation/virtual/kvm/api.txt   |   16 +++
 arch/powerpc/include/asm/kvm_host.h |    2 +
 arch/powerpc/include/uapi/asm/kvm.h |   22 ++++
 arch/powerpc/kvm/44x.c              |   12 +++
 arch/powerpc/kvm/Kconfig            |    6 +-
 arch/powerpc/kvm/booke.c            |   83 ++++++++++-------
 arch/powerpc/kvm/e500.c             |   14 +++
 arch/powerpc/kvm/e500.h             |   25 +++++
 arch/powerpc/kvm/e500_emulate.c     |   19 ++++
 arch/powerpc/kvm/e500_mmu.c         |  181 ++++++++++++++++++++++++++++++----
 arch/powerpc/kvm/e500mc.c           |   16 +++
 11 files changed, 337 insertions(+), 59 deletions(-)

-- 
1.7.4.1

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

* [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core
@ 2013-03-26 22:05 ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Enable basic support for Freescale e6500 core, adding MAV 2.0 support.
Validated on T4240QDS platfrom. Altivec, Multithreading and HW Tablewalk
are not addressed by this patchset.

Mihai Caraman (7):
  KVM: PPC: e500: Expose MMU registers via ONE_REG
  KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
  KVM: PPC: e500: Add support for TLBnPS registers
  KVM: PPC: e500: Add support for EPTCFG register
  KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  KVM: PPC: e500mc: Enable e6500 cores
  KVM: PPC: e500: Add e6500 core to Kconfig description

 Documentation/virtual/kvm/api.txt   |   16 +++
 arch/powerpc/include/asm/kvm_host.h |    2 +
 arch/powerpc/include/uapi/asm/kvm.h |   22 ++++
 arch/powerpc/kvm/44x.c              |   12 +++
 arch/powerpc/kvm/Kconfig            |    6 +-
 arch/powerpc/kvm/booke.c            |   83 ++++++++++-------
 arch/powerpc/kvm/e500.c             |   14 +++
 arch/powerpc/kvm/e500.h             |   25 +++++
 arch/powerpc/kvm/e500_emulate.c     |   19 ++++
 arch/powerpc/kvm/e500_mmu.c         |  181 ++++++++++++++++++++++++++++++----
 arch/powerpc/kvm/e500mc.c           |   16 +++
 11 files changed, 337 insertions(+), 59 deletions(-)

-- 
1.7.4.1



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

* [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

MMU registers were exposed to user-space using sregs interface. Add them
to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg delegation
interface introduced by book3s.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Restrict set_one_reg operation for MMU registers to HW values

 Documentation/virtual/kvm/api.txt   |   11 +++++
 arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
 arch/powerpc/kvm/44x.c              |   12 +++++
 arch/powerpc/kvm/booke.c            |   83 ++++++++++++++++++++--------------
 arch/powerpc/kvm/e500.c             |   14 ++++++
 arch/powerpc/kvm/e500.h             |    4 ++
 arch/powerpc/kvm/e500_mmu.c         |   84 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/e500mc.c           |   14 ++++++
 8 files changed, 205 insertions(+), 34 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 976eb65..1a76663 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1792,6 +1792,17 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TSR	| 32
   PPC   | KVM_REG_PPC_OR_TSR	| 32
   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
+  PPC   | KVM_REG_PPC_MAS0	| 32
+  PPC   | KVM_REG_PPC_MAS1	| 32
+  PPC   | KVM_REG_PPC_MAS2	| 64
+  PPC   | KVM_REG_PPC_MAS7_3	| 64
+  PPC   | KVM_REG_PPC_MAS4	| 32
+  PPC   | KVM_REG_PPC_MAS6	| 32
+  PPC   | KVM_REG_PPC_MMUCFG	| 32
+  PPC   | KVM_REG_PPC_TLB0CFG	| 32
+  PPC   | KVM_REG_PPC_TLB1CFG	| 32
+  PPC   | KVM_REG_PPC_TLB2CFG	| 32
+  PPC   | KVM_REG_PPC_TLB3CFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ef072b1..777dc81 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -422,4 +422,21 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
 #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
 #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
+
+/* MMU registers */
+#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
+#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
+#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
+#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
+#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
+#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
+#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
+/*
+ * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
+ * KVM_CAP_SW_TLB ioctl
+ */
+#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
+#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
+#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
+#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 3d7fd21..2f5c6b6 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_44x *vcpu_44x;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 58057d6..c67e99f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.iac[iac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
 		u32 epr = get_guest_epr(vcpu);
-		r = put_user(epr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR:
-		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.epcr);
 		break;
 #endif
 	case KVM_REG_PPC_TCR:
-		r = put_user(vcpu->arch.tcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tcr);
 		break;
 	case KVM_REG_PPC_TSR:
-		r = put_user(vcpu->arch.tsr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tsr);
 		break;
 	default:
+		r = kvmppc_get_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
+	if (r)
+		return r;
+
+	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
+		r = -EFAULT;
+
 	return r;
 }
 
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
+
+	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
+		return -EFAULT;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
-		u32 new_epr;
-		r = get_user(new_epr, (u32 __user *)(long)reg->addr);
-		if (!r)
-			kvmppc_set_epr(vcpu, new_epr);
+		u32 new_epr = set_reg_val(reg->id, val);
+		kvmppc_set_epr(vcpu, new_epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR: {
-		u32 new_epcr;
-		r = get_user(new_epcr, (u32 __user *)(long)reg->addr);
-		if (r == 0)
-			kvmppc_set_epcr(vcpu, new_epcr);
+		u32 new_epcr = set_reg_val(reg->id, val);
+		kvmppc_set_epcr(vcpu, new_epcr);
 		break;
 	}
 #endif
 	case KVM_REG_PPC_OR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_CLEAR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_TSR: {
-		u32 tsr;
-		r = get_user(tsr, (u32 __user *)(long)reg->addr);
+		u32 tsr = set_reg_val(reg->id, val);
 		kvmppc_set_tsr(vcpu, tsr);
 		break;
 	}
 	case KVM_REG_PPC_TCR: {
-		u32 tcr;
-		r = get_user(tcr, (u32 __user *)(long)reg->addr);
+		u32 tcr = set_reg_val(reg->id, val);
 		kvmppc_set_tcr(vcpu, tcr);
 		break;
 	}
 	default:
+		r = kvmppc_set_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
 	return r;
 }
 
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 6dd4de7..ce6b73c 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 33db48a..b73ca7a 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
 void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val);
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val);
 
 #ifdef CONFIG_KVM_E500V2
 unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 5c44759..68c2b00 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return 0;
 }
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		*val = get_reg_val(id, vcpu->arch.shared->mas0);
+	case KVM_REG_PPC_MAS1:
+		*val = get_reg_val(id, vcpu->arch.shared->mas1);
+	case KVM_REG_PPC_MAS2:
+		*val = get_reg_val(id, vcpu->arch.shared->mas2);
+	case KVM_REG_PPC_MAS7_3:
+		*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
+	case KVM_REG_PPC_MAS4:
+		*val = get_reg_val(id, vcpu->arch.shared->mas4);
+	case KVM_REG_PPC_MAS6:
+		*val = get_reg_val(id, vcpu->arch.shared->mas6);
+	case KVM_REG_PPC_MMUCFG:
+		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG:
+		i = id - KVM_REG_PPC_TLB0CFG;
+		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS1:
+		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS2:
+		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS7_3:
+		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS4:
+		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS6:
+		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
+		break;
+	/* Only allow MMU registers to be set to the config supported by KVM */
+	case KVM_REG_PPC_MMUCFG: {
+		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
+			r = -EINVAL;
+		break;
+	}
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG: {
+		/* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
+		i = id - KVM_REG_PPC_TLB0CFG;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
+			r = -EINVAL;
+		break;
+	}
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..ab073a8 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
-- 
1.7.4.1

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

* [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

MMU registers were exposed to user-space using sregs interface. Add them
to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg delegation
interface introduced by book3s.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Restrict set_one_reg operation for MMU registers to HW values

 Documentation/virtual/kvm/api.txt   |   11 +++++
 arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
 arch/powerpc/kvm/44x.c              |   12 +++++
 arch/powerpc/kvm/booke.c            |   83 ++++++++++++++++++++--------------
 arch/powerpc/kvm/e500.c             |   14 ++++++
 arch/powerpc/kvm/e500.h             |    4 ++
 arch/powerpc/kvm/e500_mmu.c         |   84 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/e500mc.c           |   14 ++++++
 8 files changed, 205 insertions(+), 34 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 976eb65..1a76663 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1792,6 +1792,17 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TSR	| 32
   PPC   | KVM_REG_PPC_OR_TSR	| 32
   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
+  PPC   | KVM_REG_PPC_MAS0	| 32
+  PPC   | KVM_REG_PPC_MAS1	| 32
+  PPC   | KVM_REG_PPC_MAS2	| 64
+  PPC   | KVM_REG_PPC_MAS7_3	| 64
+  PPC   | KVM_REG_PPC_MAS4	| 32
+  PPC   | KVM_REG_PPC_MAS6	| 32
+  PPC   | KVM_REG_PPC_MMUCFG	| 32
+  PPC   | KVM_REG_PPC_TLB0CFG	| 32
+  PPC   | KVM_REG_PPC_TLB1CFG	| 32
+  PPC   | KVM_REG_PPC_TLB2CFG	| 32
+  PPC   | KVM_REG_PPC_TLB3CFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ef072b1..777dc81 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -422,4 +422,21 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
 #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
 #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
+
+/* MMU registers */
+#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
+#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
+#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
+#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
+#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
+#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
+#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
+/*
+ * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
+ * KVM_CAP_SW_TLB ioctl
+ */
+#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
+#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
+#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
+#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 3d7fd21..2f5c6b6 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_44x *vcpu_44x;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 58057d6..c67e99f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.iac[iac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
 		u32 epr = get_guest_epr(vcpu);
-		r = put_user(epr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR:
-		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.epcr);
 		break;
 #endif
 	case KVM_REG_PPC_TCR:
-		r = put_user(vcpu->arch.tcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tcr);
 		break;
 	case KVM_REG_PPC_TSR:
-		r = put_user(vcpu->arch.tsr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tsr);
 		break;
 	default:
+		r = kvmppc_get_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
+	if (r)
+		return r;
+
+	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
+		r = -EFAULT;
+
 	return r;
 }
 
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
+
+	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
+		return -EFAULT;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
-		u32 new_epr;
-		r = get_user(new_epr, (u32 __user *)(long)reg->addr);
-		if (!r)
-			kvmppc_set_epr(vcpu, new_epr);
+		u32 new_epr = set_reg_val(reg->id, val);
+		kvmppc_set_epr(vcpu, new_epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR: {
-		u32 new_epcr;
-		r = get_user(new_epcr, (u32 __user *)(long)reg->addr);
-		if (r == 0)
-			kvmppc_set_epcr(vcpu, new_epcr);
+		u32 new_epcr = set_reg_val(reg->id, val);
+		kvmppc_set_epcr(vcpu, new_epcr);
 		break;
 	}
 #endif
 	case KVM_REG_PPC_OR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_CLEAR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_TSR: {
-		u32 tsr;
-		r = get_user(tsr, (u32 __user *)(long)reg->addr);
+		u32 tsr = set_reg_val(reg->id, val);
 		kvmppc_set_tsr(vcpu, tsr);
 		break;
 	}
 	case KVM_REG_PPC_TCR: {
-		u32 tcr;
-		r = get_user(tcr, (u32 __user *)(long)reg->addr);
+		u32 tcr = set_reg_val(reg->id, val);
 		kvmppc_set_tcr(vcpu, tcr);
 		break;
 	}
 	default:
+		r = kvmppc_set_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
 	return r;
 }
 
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 6dd4de7..ce6b73c 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 33db48a..b73ca7a 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
 void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val);
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val);
 
 #ifdef CONFIG_KVM_E500V2
 unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 5c44759..68c2b00 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return 0;
 }
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		*val = get_reg_val(id, vcpu->arch.shared->mas0);
+	case KVM_REG_PPC_MAS1:
+		*val = get_reg_val(id, vcpu->arch.shared->mas1);
+	case KVM_REG_PPC_MAS2:
+		*val = get_reg_val(id, vcpu->arch.shared->mas2);
+	case KVM_REG_PPC_MAS7_3:
+		*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
+	case KVM_REG_PPC_MAS4:
+		*val = get_reg_val(id, vcpu->arch.shared->mas4);
+	case KVM_REG_PPC_MAS6:
+		*val = get_reg_val(id, vcpu->arch.shared->mas6);
+	case KVM_REG_PPC_MMUCFG:
+		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG:
+		i = id - KVM_REG_PPC_TLB0CFG;
+		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS1:
+		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS2:
+		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS7_3:
+		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS4:
+		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS6:
+		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
+		break;
+	/* Only allow MMU registers to be set to the config supported by KVM */
+	case KVM_REG_PPC_MMUCFG: {
+		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
+			r = -EINVAL;
+		break;
+	}
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG: {
+		/* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
+		i = id - KVM_REG_PPC_TLB0CFG;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
+			r = -EINVAL;
+		break;
+	}
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..ab073a8 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
-- 
1.7.4.1

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

* [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

MMU registers were exposed to user-space using sregs interface. Add them
to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg delegation
interface introduced by book3s.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Restrict set_one_reg operation for MMU registers to HW values

 Documentation/virtual/kvm/api.txt   |   11 +++++
 arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
 arch/powerpc/kvm/44x.c              |   12 +++++
 arch/powerpc/kvm/booke.c            |   83 ++++++++++++++++++++--------------
 arch/powerpc/kvm/e500.c             |   14 ++++++
 arch/powerpc/kvm/e500.h             |    4 ++
 arch/powerpc/kvm/e500_mmu.c         |   84 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/e500mc.c           |   14 ++++++
 8 files changed, 205 insertions(+), 34 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 976eb65..1a76663 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1792,6 +1792,17 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TSR	| 32
   PPC   | KVM_REG_PPC_OR_TSR	| 32
   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
+  PPC   | KVM_REG_PPC_MAS0	| 32
+  PPC   | KVM_REG_PPC_MAS1	| 32
+  PPC   | KVM_REG_PPC_MAS2	| 64
+  PPC   | KVM_REG_PPC_MAS7_3	| 64
+  PPC   | KVM_REG_PPC_MAS4	| 32
+  PPC   | KVM_REG_PPC_MAS6	| 32
+  PPC   | KVM_REG_PPC_MMUCFG	| 32
+  PPC   | KVM_REG_PPC_TLB0CFG	| 32
+  PPC   | KVM_REG_PPC_TLB1CFG	| 32
+  PPC   | KVM_REG_PPC_TLB2CFG	| 32
+  PPC   | KVM_REG_PPC_TLB3CFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ef072b1..777dc81 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -422,4 +422,21 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
 #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
 #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
+
+/* MMU registers */
+#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
+#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
+#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
+#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
+#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
+#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
+#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
+/*
+ * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
+ * KVM_CAP_SW_TLB ioctl
+ */
+#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
+#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
+#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
+#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 3d7fd21..2f5c6b6 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	return -EINVAL;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_44x *vcpu_44x;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 58057d6..c67e99f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.iac[iac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_to_user((u64 __user *)(long)reg->addr,
-				 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
 		u32 epr = get_guest_epr(vcpu);
-		r = put_user(epr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR:
-		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.epcr);
 		break;
 #endif
 	case KVM_REG_PPC_TCR:
-		r = put_user(vcpu->arch.tcr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tcr);
 		break;
 	case KVM_REG_PPC_TSR:
-		r = put_user(vcpu->arch.tsr, (u32 __user *)(long)reg->addr);
+		val = get_reg_val(reg->id, vcpu->arch.tsr);
 		break;
 	default:
+		r = kvmppc_get_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
+	if (r)
+		return r;
+
+	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
+		r = -EFAULT;
+
 	return r;
 }
 
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 {
-	int r = -EINVAL;
+	int r = 0;
+	union kvmppc_one_reg val;
+	int size;
+	long int i;
+
+	size = one_reg_size(reg->id);
+	if (size > sizeof(val))
+		return -EINVAL;
+
+	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
+		return -EFAULT;
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
 	case KVM_REG_PPC_IAC2:
 	case KVM_REG_PPC_IAC3:
 	case KVM_REG_PPC_IAC4: {
-		int iac = reg->id - KVM_REG_PPC_IAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_IAC1;
+		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_DAC1:
 	case KVM_REG_PPC_DAC2: {
-		int dac = reg->id - KVM_REG_PPC_DAC1;
-		r = copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
-			     (u64 __user *)(long)reg->addr, sizeof(u64));
+		i = reg->id - KVM_REG_PPC_DAC1;
+		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
 		break;
 	}
 	case KVM_REG_PPC_EPR: {
-		u32 new_epr;
-		r = get_user(new_epr, (u32 __user *)(long)reg->addr);
-		if (!r)
-			kvmppc_set_epr(vcpu, new_epr);
+		u32 new_epr = set_reg_val(reg->id, val);
+		kvmppc_set_epr(vcpu, new_epr);
 		break;
 	}
 #if defined(CONFIG_64BIT)
 	case KVM_REG_PPC_EPCR: {
-		u32 new_epcr;
-		r = get_user(new_epcr, (u32 __user *)(long)reg->addr);
-		if (r = 0)
-			kvmppc_set_epcr(vcpu, new_epcr);
+		u32 new_epcr = set_reg_val(reg->id, val);
+		kvmppc_set_epcr(vcpu, new_epcr);
 		break;
 	}
 #endif
 	case KVM_REG_PPC_OR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_CLEAR_TSR: {
-		u32 tsr_bits;
-		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
+		u32 tsr_bits = set_reg_val(reg->id, val);
 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
 		break;
 	}
 	case KVM_REG_PPC_TSR: {
-		u32 tsr;
-		r = get_user(tsr, (u32 __user *)(long)reg->addr);
+		u32 tsr = set_reg_val(reg->id, val);
 		kvmppc_set_tsr(vcpu, tsr);
 		break;
 	}
 	case KVM_REG_PPC_TCR: {
-		u32 tcr;
-		r = get_user(tcr, (u32 __user *)(long)reg->addr);
+		u32 tcr = set_reg_val(reg->id, val);
 		kvmppc_set_tcr(vcpu, tcr);
 		break;
 	}
 	default:
+		r = kvmppc_set_one_reg(vcpu, reg->id, &val);
 		break;
 	}
+
 	return r;
 }
 
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 6dd4de7..ce6b73c 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 33db48a..b73ca7a 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
 void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val);
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val);
 
 #ifdef CONFIG_KVM_E500V2
 unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 5c44759..68c2b00 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return 0;
 }
 
+int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		*val = get_reg_val(id, vcpu->arch.shared->mas0);
+	case KVM_REG_PPC_MAS1:
+		*val = get_reg_val(id, vcpu->arch.shared->mas1);
+	case KVM_REG_PPC_MAS2:
+		*val = get_reg_val(id, vcpu->arch.shared->mas2);
+	case KVM_REG_PPC_MAS7_3:
+		*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
+	case KVM_REG_PPC_MAS4:
+		*val = get_reg_val(id, vcpu->arch.shared->mas4);
+	case KVM_REG_PPC_MAS6:
+		*val = get_reg_val(id, vcpu->arch.shared->mas6);
+	case KVM_REG_PPC_MMUCFG:
+		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG:
+		i = id - KVM_REG_PPC_TLB0CFG;
+		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
+int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
+			       union kvmppc_one_reg *val)
+{
+	int r = 0;
+	long int i;
+
+	switch (id) {
+	case KVM_REG_PPC_MAS0:
+		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS1:
+		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS2:
+		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS7_3:
+		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS4:
+		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
+		break;
+	case KVM_REG_PPC_MAS6:
+		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
+		break;
+	/* Only allow MMU registers to be set to the config supported by KVM */
+	case KVM_REG_PPC_MMUCFG: {
+		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
+			r = -EINVAL;
+		break;
+	}
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG: {
+		/* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
+		i = id - KVM_REG_PPC_TLB0CFG;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
+			r = -EINVAL;
+		break;
+	}
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..ab073a8 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
+int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
+			union kvmppc_one_reg *val)
+{
+	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
+int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
+		       union kvmppc_one_reg *val)
+{
+	int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
+	return r;
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
-- 
1.7.4.1



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

* [PATCH 2/7 v2] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Vcpu's MMU default configuration and geometry update logic was buried in
a chunk of code. Move them to dedicated functions to add more clarity.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add better patch description. Hopefully :)

 arch/powerpc/kvm/e500_mmu.c |   60 +++++++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 68c2b00..7d6bb12 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -680,6 +680,20 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	return r;
 }
 
+static int vcpu_mmu_geometry_update(struct kvm_vcpu *vcpu,
+		struct kvm_book3e_206_tlb_params *params)
+{
+	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	if (params->tlb_sizes[0] <= 2048)
+		vcpu->arch.tlbcfg[0] |= params->tlb_sizes[0];
+	vcpu->arch.tlbcfg[0] |= params->tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params->tlb_sizes[1];
+	vcpu->arch.tlbcfg[1] |= params->tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	return 0;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
@@ -776,16 +790,8 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 	vcpu_e500->gtlb_offset[0] = 0;
 	vcpu_e500->gtlb_offset[1] = params.tlb_sizes[0];
 
-	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
-
-	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	if (params.tlb_sizes[0] <= 2048)
-		vcpu->arch.tlbcfg[0] |= params.tlb_sizes[0];
-	vcpu->arch.tlbcfg[0] |= params.tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= params.tlb_sizes[1];
-	vcpu->arch.tlbcfg[1] |= params.tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	/* Update vcpu's MMU geometry based on SW_TLB input */
+	vcpu_mmu_geometry_update(vcpu, &params);
 
 	vcpu_e500->shared_tlb_pages = pages;
 	vcpu_e500->num_shared_tlb_pages = num_pages;
@@ -821,6 +827,27 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+/* Vcpu's MMU default configuration */
+static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
+		       struct kvmppc_e500_tlb_params *params)
+{
+	/* Initialize RASIZE, PIDSIZE, NTLBS and MAVN fields with host values*/
+	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
+
+	/* Initialize TLBnCFG fields with host values and SW_TLB geometry*/
+	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[0] |= params[0].entries;
+	vcpu->arch.tlbcfg[0] |= params[0].ways << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params[1].entries;
+	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
+
+	return 0;
+}
+
 int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
 	struct kvm_vcpu *vcpu = &vcpu_e500->vcpu;
@@ -865,18 +892,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 	if (!vcpu_e500->g2h_tlb1_map)
 		goto err;
 
-	/* Init TLB configuration register */
-	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[0] |= vcpu_e500->gtlb_params[0].entries;
-	vcpu->arch.tlbcfg[0] |=
-		vcpu_e500->gtlb_params[0].ways << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= vcpu_e500->gtlb_params[1].entries;
-	vcpu->arch.tlbcfg[1] |=
-		vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT;
+	vcpu_mmu_init(vcpu, vcpu_e500->gtlb_params);
 
 	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	return 0;
-- 
1.7.4.1



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

* [PATCH 2/7 v2] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Vcpu's MMU default configuration and geometry update logic was buried in
a chunk of code. Move them to dedicated functions to add more clarity.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add better patch description. Hopefully :)

 arch/powerpc/kvm/e500_mmu.c |   60 +++++++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 68c2b00..7d6bb12 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -680,6 +680,20 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	return r;
 }
 
+static int vcpu_mmu_geometry_update(struct kvm_vcpu *vcpu,
+		struct kvm_book3e_206_tlb_params *params)
+{
+	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	if (params->tlb_sizes[0] <= 2048)
+		vcpu->arch.tlbcfg[0] |= params->tlb_sizes[0];
+	vcpu->arch.tlbcfg[0] |= params->tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params->tlb_sizes[1];
+	vcpu->arch.tlbcfg[1] |= params->tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	return 0;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
@@ -776,16 +790,8 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 	vcpu_e500->gtlb_offset[0] = 0;
 	vcpu_e500->gtlb_offset[1] = params.tlb_sizes[0];
 
-	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
-
-	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	if (params.tlb_sizes[0] <= 2048)
-		vcpu->arch.tlbcfg[0] |= params.tlb_sizes[0];
-	vcpu->arch.tlbcfg[0] |= params.tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= params.tlb_sizes[1];
-	vcpu->arch.tlbcfg[1] |= params.tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	/* Update vcpu's MMU geometry based on SW_TLB input */
+	vcpu_mmu_geometry_update(vcpu, &params);
 
 	vcpu_e500->shared_tlb_pages = pages;
 	vcpu_e500->num_shared_tlb_pages = num_pages;
@@ -821,6 +827,27 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+/* Vcpu's MMU default configuration */
+static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
+		       struct kvmppc_e500_tlb_params *params)
+{
+	/* Initialize RASIZE, PIDSIZE, NTLBS and MAVN fields with host values*/
+	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
+
+	/* Initialize TLBnCFG fields with host values and SW_TLB geometry*/
+	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[0] |= params[0].entries;
+	vcpu->arch.tlbcfg[0] |= params[0].ways << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params[1].entries;
+	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
+
+	return 0;
+}
+
 int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
 	struct kvm_vcpu *vcpu = &vcpu_e500->vcpu;
@@ -865,18 +892,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 	if (!vcpu_e500->g2h_tlb1_map)
 		goto err;
 
-	/* Init TLB configuration register */
-	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[0] |= vcpu_e500->gtlb_params[0].entries;
-	vcpu->arch.tlbcfg[0] |=
-		vcpu_e500->gtlb_params[0].ways << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= vcpu_e500->gtlb_params[1].entries;
-	vcpu->arch.tlbcfg[1] |=
-		vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT;
+	vcpu_mmu_init(vcpu, vcpu_e500->gtlb_params);
 
 	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	return 0;
-- 
1.7.4.1

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

* [PATCH 2/7 v2] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Vcpu's MMU default configuration and geometry update logic was buried in
a chunk of code. Move them to dedicated functions to add more clarity.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add better patch description. Hopefully :)

 arch/powerpc/kvm/e500_mmu.c |   60 +++++++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 68c2b00..7d6bb12 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -680,6 +680,20 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	return r;
 }
 
+static int vcpu_mmu_geometry_update(struct kvm_vcpu *vcpu,
+		struct kvm_book3e_206_tlb_params *params)
+{
+	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	if (params->tlb_sizes[0] <= 2048)
+		vcpu->arch.tlbcfg[0] |= params->tlb_sizes[0];
+	vcpu->arch.tlbcfg[0] |= params->tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params->tlb_sizes[1];
+	vcpu->arch.tlbcfg[1] |= params->tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	return 0;
+}
+
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 			      struct kvm_config_tlb *cfg)
 {
@@ -776,16 +790,8 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 	vcpu_e500->gtlb_offset[0] = 0;
 	vcpu_e500->gtlb_offset[1] = params.tlb_sizes[0];
 
-	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
-
-	vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	if (params.tlb_sizes[0] <= 2048)
-		vcpu->arch.tlbcfg[0] |= params.tlb_sizes[0];
-	vcpu->arch.tlbcfg[0] |= params.tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= params.tlb_sizes[1];
-	vcpu->arch.tlbcfg[1] |= params.tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
+	/* Update vcpu's MMU geometry based on SW_TLB input */
+	vcpu_mmu_geometry_update(vcpu, &params);
 
 	vcpu_e500->shared_tlb_pages = pages;
 	vcpu_e500->num_shared_tlb_pages = num_pages;
@@ -821,6 +827,27 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+/* Vcpu's MMU default configuration */
+static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
+		       struct kvmppc_e500_tlb_params *params)
+{
+	/* Initialize RASIZE, PIDSIZE, NTLBS and MAVN fields with host values*/
+	vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
+
+	/* Initialize TLBnCFG fields with host values and SW_TLB geometry*/
+	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[0] |= params[0].entries;
+	vcpu->arch.tlbcfg[0] |= params[0].ways << TLBnCFG_ASSOC_SHIFT;
+
+	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
+			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
+	vcpu->arch.tlbcfg[1] |= params[1].entries;
+	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
+
+	return 0;
+}
+
 int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
 	struct kvm_vcpu *vcpu = &vcpu_e500->vcpu;
@@ -865,18 +892,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 	if (!vcpu_e500->g2h_tlb1_map)
 		goto err;
 
-	/* Init TLB configuration register */
-	vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[0] |= vcpu_e500->gtlb_params[0].entries;
-	vcpu->arch.tlbcfg[0] |-		vcpu_e500->gtlb_params[0].ways << TLBnCFG_ASSOC_SHIFT;
-
-	vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
-			     ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
-	vcpu->arch.tlbcfg[1] |= vcpu_e500->gtlb_params[1].entries;
-	vcpu->arch.tlbcfg[1] |-		vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT;
+	vcpu_mmu_init(vcpu, vcpu_e500->gtlb_params);
 
 	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	return 0;
-- 
1.7.4.1



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

* [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Add support for TLBnPS registers available in MMU Architecture Version
(MAV) 2.0.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add vcpu generic function has_feature()

 Documentation/virtual/kvm/api.txt   |    4 ++++
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    4 ++++
 arch/powerpc/kvm/e500.h             |   16 ++++++++++++++++
 arch/powerpc/kvm/e500_emulate.c     |   10 ++++++++++
 arch/powerpc/kvm/e500_mmu.c         |   20 ++++++++++++++++++++
 6 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1a76663..f045377 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1803,6 +1803,10 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1CFG	| 32
   PPC   | KVM_REG_PPC_TLB2CFG	| 32
   PPC   | KVM_REG_PPC_TLB3CFG	| 32
+  PPC   | KVM_REG_PPC_TLB0PS	| 32
+  PPC   | KVM_REG_PPC_TLB1PS	| 32
+  PPC   | KVM_REG_PPC_TLB2PS	| 32
+  PPC   | KVM_REG_PPC_TLB3PS	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e34f8fe..3b6cee3 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -502,6 +502,7 @@ struct kvm_vcpu_arch {
 	spinlock_t wdt_lock;
 	struct timer_list wdt_timer;
 	u32 tlbcfg[4];
+	u32 tlbps[4];
 	u32 mmucfg;
 	u32 epr;
 	u32 crit_save;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 777dc81..7cfd13f 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -439,4 +439,8 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
 #define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
 #define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
+#define KVM_REG_PPC_TLB0PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
+#define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
+#define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
+#define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index b73ca7a..795934d 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -23,6 +23,8 @@
 #include <asm/mmu-book3e.h>
 #include <asm/tlb.h>
 
+#define VCPU_FTR_MMU_V2		0
+
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
 
@@ -299,4 +301,18 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
 #define get_tlb_sts(gtlbe)              (MAS1_TS)
 #endif /* !BOOKE_HV */
 
+static inline bool has_feature(const struct kvm_vcpu *vcpu,
+			       unsigned long vcpu_ftr)
+{
+	bool has_ftr;
+	switch (vcpu_ftr) {
+	case VCPU_FTR_MMU_V2:
+		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
+		break;
+	default:
+		has_ftr = false;
+	}
+	return has_ftr;
+}
+
 #endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e78f353..12b8de2 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -284,6 +284,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_TLB1CFG:
 		*spr_val = vcpu->arch.tlbcfg[1];
 		break;
+	case SPRN_TLB0PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[0];
+		break;
+	case SPRN_TLB1PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[1];
+		break;
 	case SPRN_L1CSR0:
 		*spr_val = vcpu_e500->l1csr0;
 		break;
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 7d6bb12..e354fa1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -623,6 +623,12 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	case KVM_REG_PPC_TLB3CFG:
 		i = id - KVM_REG_PPC_TLB0CFG;
 		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS:
+		i = id - KVM_REG_PPC_TLB0PS;
+		*val = get_reg_val(id, vcpu->arch.tlbps[i]);
 	default:
 		r = -EINVAL;
 		break;
@@ -672,6 +678,15 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS: {
+		i = id - KVM_REG_PPC_TLB0PS;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbps[i])
+			r = -EINVAL;
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
@@ -845,6 +860,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].entries;
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
+	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
+		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
+	}
+
 	return 0;
 }
 
-- 
1.7.4.1

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

* [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Add support for TLBnPS registers available in MMU Architecture Version
(MAV) 2.0.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add vcpu generic function has_feature()

 Documentation/virtual/kvm/api.txt   |    4 ++++
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    4 ++++
 arch/powerpc/kvm/e500.h             |   16 ++++++++++++++++
 arch/powerpc/kvm/e500_emulate.c     |   10 ++++++++++
 arch/powerpc/kvm/e500_mmu.c         |   20 ++++++++++++++++++++
 6 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1a76663..f045377 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1803,6 +1803,10 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1CFG	| 32
   PPC   | KVM_REG_PPC_TLB2CFG	| 32
   PPC   | KVM_REG_PPC_TLB3CFG	| 32
+  PPC   | KVM_REG_PPC_TLB0PS	| 32
+  PPC   | KVM_REG_PPC_TLB1PS	| 32
+  PPC   | KVM_REG_PPC_TLB2PS	| 32
+  PPC   | KVM_REG_PPC_TLB3PS	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e34f8fe..3b6cee3 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -502,6 +502,7 @@ struct kvm_vcpu_arch {
 	spinlock_t wdt_lock;
 	struct timer_list wdt_timer;
 	u32 tlbcfg[4];
+	u32 tlbps[4];
 	u32 mmucfg;
 	u32 epr;
 	u32 crit_save;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 777dc81..7cfd13f 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -439,4 +439,8 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
 #define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
 #define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
+#define KVM_REG_PPC_TLB0PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
+#define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
+#define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
+#define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index b73ca7a..795934d 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -23,6 +23,8 @@
 #include <asm/mmu-book3e.h>
 #include <asm/tlb.h>
 
+#define VCPU_FTR_MMU_V2		0
+
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
 
@@ -299,4 +301,18 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
 #define get_tlb_sts(gtlbe)              (MAS1_TS)
 #endif /* !BOOKE_HV */
 
+static inline bool has_feature(const struct kvm_vcpu *vcpu,
+			       unsigned long vcpu_ftr)
+{
+	bool has_ftr;
+	switch (vcpu_ftr) {
+	case VCPU_FTR_MMU_V2:
+		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
+		break;
+	default:
+		has_ftr = false;
+	}
+	return has_ftr;
+}
+
 #endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e78f353..12b8de2 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -284,6 +284,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_TLB1CFG:
 		*spr_val = vcpu->arch.tlbcfg[1];
 		break;
+	case SPRN_TLB0PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[0];
+		break;
+	case SPRN_TLB1PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[1];
+		break;
 	case SPRN_L1CSR0:
 		*spr_val = vcpu_e500->l1csr0;
 		break;
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 7d6bb12..e354fa1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -623,6 +623,12 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	case KVM_REG_PPC_TLB3CFG:
 		i = id - KVM_REG_PPC_TLB0CFG;
 		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS:
+		i = id - KVM_REG_PPC_TLB0PS;
+		*val = get_reg_val(id, vcpu->arch.tlbps[i]);
 	default:
 		r = -EINVAL;
 		break;
@@ -672,6 +678,15 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS: {
+		i = id - KVM_REG_PPC_TLB0PS;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbps[i])
+			r = -EINVAL;
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
@@ -845,6 +860,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].entries;
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
+	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
+		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
+	}
+
 	return 0;
 }
 
-- 
1.7.4.1

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

* [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Add support for TLBnPS registers available in MMU Architecture Version
(MAV) 2.0.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Add vcpu generic function has_feature()

 Documentation/virtual/kvm/api.txt   |    4 ++++
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    4 ++++
 arch/powerpc/kvm/e500.h             |   16 ++++++++++++++++
 arch/powerpc/kvm/e500_emulate.c     |   10 ++++++++++
 arch/powerpc/kvm/e500_mmu.c         |   20 ++++++++++++++++++++
 6 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1a76663..f045377 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1803,6 +1803,10 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1CFG	| 32
   PPC   | KVM_REG_PPC_TLB2CFG	| 32
   PPC   | KVM_REG_PPC_TLB3CFG	| 32
+  PPC   | KVM_REG_PPC_TLB0PS	| 32
+  PPC   | KVM_REG_PPC_TLB1PS	| 32
+  PPC   | KVM_REG_PPC_TLB2PS	| 32
+  PPC   | KVM_REG_PPC_TLB3PS	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e34f8fe..3b6cee3 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -502,6 +502,7 @@ struct kvm_vcpu_arch {
 	spinlock_t wdt_lock;
 	struct timer_list wdt_timer;
 	u32 tlbcfg[4];
+	u32 tlbps[4];
 	u32 mmucfg;
 	u32 epr;
 	u32 crit_save;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 777dc81..7cfd13f 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -439,4 +439,8 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
 #define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
 #define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
+#define KVM_REG_PPC_TLB0PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
+#define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
+#define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
+#define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index b73ca7a..795934d 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -23,6 +23,8 @@
 #include <asm/mmu-book3e.h>
 #include <asm/tlb.h>
 
+#define VCPU_FTR_MMU_V2		0
+
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
 
@@ -299,4 +301,18 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
 #define get_tlb_sts(gtlbe)              (MAS1_TS)
 #endif /* !BOOKE_HV */
 
+static inline bool has_feature(const struct kvm_vcpu *vcpu,
+			       unsigned long vcpu_ftr)
+{
+	bool has_ftr;
+	switch (vcpu_ftr) {
+	case VCPU_FTR_MMU_V2:
+		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) = MMUCFG_MAVN_V2);
+		break;
+	default:
+		has_ftr = false;
+	}
+	return has_ftr;
+}
+
 #endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e78f353..12b8de2 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -284,6 +284,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_TLB1CFG:
 		*spr_val = vcpu->arch.tlbcfg[1];
 		break;
+	case SPRN_TLB0PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[0];
+		break;
+	case SPRN_TLB1PS:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		*spr_val = vcpu->arch.tlbps[1];
+		break;
 	case SPRN_L1CSR0:
 		*spr_val = vcpu_e500->l1csr0;
 		break;
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 7d6bb12..e354fa1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -623,6 +623,12 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 	case KVM_REG_PPC_TLB3CFG:
 		i = id - KVM_REG_PPC_TLB0CFG;
 		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS:
+		i = id - KVM_REG_PPC_TLB0PS;
+		*val = get_reg_val(id, vcpu->arch.tlbps[i]);
 	default:
 		r = -EINVAL;
 		break;
@@ -672,6 +678,15 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_TLB0PS:
+	case KVM_REG_PPC_TLB1PS:
+	case KVM_REG_PPC_TLB2PS:
+	case KVM_REG_PPC_TLB3PS: {
+		i = id - KVM_REG_PPC_TLB0PS;
+		if (set_reg_val(id, *val) != vcpu->arch.tlbps[i])
+			r = -EINVAL;
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
@@ -845,6 +860,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].entries;
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
+	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
+		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
+	}
+
 	return 0;
 }
 
-- 
1.7.4.1



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

* [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
in the presence of MAV 2.0. Support it now.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Use has_feature() function

 Documentation/virtual/kvm/api.txt   |    1 +
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    1 +
 arch/powerpc/kvm/e500.h             |    5 +++++
 arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
 arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
 6 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index f045377..a1f2200 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1807,6 +1807,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1PS	| 32
   PPC   | KVM_REG_PPC_TLB2PS	| 32
   PPC   | KVM_REG_PPC_TLB3PS	| 32
+  PPC   | KVM_REG_PPC_EPTCFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3b6cee3..8a48e68 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 tlbps[4];
 	u32 mmucfg;
+	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
 	struct kvmppc_booke_debug_reg dbg_reg;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 7cfd13f..9d7fbf0 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,4 +443,5 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
 #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
 #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
+#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 795934d..6cfc669 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -24,6 +24,7 @@
 #include <asm/tlb.h>
 
 #define VCPU_FTR_MMU_V2		0
+#define VCPU_FTR_E_PT		1
 
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
@@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
 	case VCPU_FTR_MMU_V2:
 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
 		break;
+	case VCPU_FTR_E_PT:
+		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
+			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
+		break;
 	default:
 		has_ftr = false;
 	}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 12b8de2..b10a012 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_MMUCFG:
 		*spr_val = vcpu->arch.mmucfg;
 		break;
+	case SPRN_EPTCFG:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		/*
+		 * Legacy Linux guests access EPTCFG register even if the E.PT
+		 * category is disabled in the VM. Give them a chance to live.
+		 */
+		*spr_val = vcpu->arch.eptcfg;
+		break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index e354fa1..cf60db1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
 	case KVM_REG_PPC_MMUCFG:
 		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_EPTCFG:
+		*val = get_reg_val(id, vcpu->arch.eptcfg);
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_EPTCFG:
+		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
+			r = -EINVAL;
+		break;
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		if (has_feature(vcpu, VCPU_FTR_E_PT))
+			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
+		else
+			vcpu->arch.eptcfg = 0;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1



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

* [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
in the presence of MAV 2.0. Support it now.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Use has_feature() function

 Documentation/virtual/kvm/api.txt   |    1 +
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    1 +
 arch/powerpc/kvm/e500.h             |    5 +++++
 arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
 arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
 6 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index f045377..a1f2200 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1807,6 +1807,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1PS	| 32
   PPC   | KVM_REG_PPC_TLB2PS	| 32
   PPC   | KVM_REG_PPC_TLB3PS	| 32
+  PPC   | KVM_REG_PPC_EPTCFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3b6cee3..8a48e68 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 tlbps[4];
 	u32 mmucfg;
+	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
 	struct kvmppc_booke_debug_reg dbg_reg;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 7cfd13f..9d7fbf0 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,4 +443,5 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
 #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
 #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
+#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 795934d..6cfc669 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -24,6 +24,7 @@
 #include <asm/tlb.h>
 
 #define VCPU_FTR_MMU_V2		0
+#define VCPU_FTR_E_PT		1
 
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
@@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
 	case VCPU_FTR_MMU_V2:
 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
 		break;
+	case VCPU_FTR_E_PT:
+		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
+			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
+		break;
 	default:
 		has_ftr = false;
 	}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 12b8de2..b10a012 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_MMUCFG:
 		*spr_val = vcpu->arch.mmucfg;
 		break;
+	case SPRN_EPTCFG:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		/*
+		 * Legacy Linux guests access EPTCFG register even if the E.PT
+		 * category is disabled in the VM. Give them a chance to live.
+		 */
+		*spr_val = vcpu->arch.eptcfg;
+		break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index e354fa1..cf60db1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
 	case KVM_REG_PPC_MMUCFG:
 		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_EPTCFG:
+		*val = get_reg_val(id, vcpu->arch.eptcfg);
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_EPTCFG:
+		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
+			r = -EINVAL;
+		break;
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		if (has_feature(vcpu, VCPU_FTR_E_PT))
+			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
+		else
+			vcpu->arch.eptcfg = 0;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1

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

* [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
in the presence of MAV 2.0. Support it now.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Use has_feature() function

 Documentation/virtual/kvm/api.txt   |    1 +
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    1 +
 arch/powerpc/kvm/e500.h             |    5 +++++
 arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
 arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
 6 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index f045377..a1f2200 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1807,6 +1807,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1PS	| 32
   PPC   | KVM_REG_PPC_TLB2PS	| 32
   PPC   | KVM_REG_PPC_TLB3PS	| 32
+  PPC   | KVM_REG_PPC_EPTCFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3b6cee3..8a48e68 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 tlbps[4];
 	u32 mmucfg;
+	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
 	struct kvmppc_booke_debug_reg dbg_reg;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 7cfd13f..9d7fbf0 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,4 +443,5 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
 #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
 #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
+#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 795934d..6cfc669 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -24,6 +24,7 @@
 #include <asm/tlb.h>
 
 #define VCPU_FTR_MMU_V2		0
+#define VCPU_FTR_E_PT		1
 
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
@@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
 	case VCPU_FTR_MMU_V2:
 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) = MMUCFG_MAVN_V2);
 		break;
+	case VCPU_FTR_E_PT:
+		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
+			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
+		break;
 	default:
 		has_ftr = false;
 	}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 12b8de2..b10a012 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_MMUCFG:
 		*spr_val = vcpu->arch.mmucfg;
 		break;
+	case SPRN_EPTCFG:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		/*
+		 * Legacy Linux guests access EPTCFG register even if the E.PT
+		 * category is disabled in the VM. Give them a chance to live.
+		 */
+		*spr_val = vcpu->arch.eptcfg;
+		break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index e354fa1..cf60db1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
 	case KVM_REG_PPC_MMUCFG:
 		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_EPTCFG:
+		*val = get_reg_val(id, vcpu->arch.eptcfg);
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_EPTCFG:
+		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
+			r = -EINVAL;
+		break;
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		if (has_feature(vcpu, VCPU_FTR_E_PT))
+			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
+		else
+			vcpu->arch.eptcfg = 0;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1



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

* [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
emulation which is not supported yet. Configure TLBnCFG to remove E.PT
and E.HV.LRAT categories from VCPUs.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Remove E.HV.LRAT from vcpus

 arch/powerpc/kvm/e500_mmu.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index cf60db1..0d2a293 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
+
 		if (has_feature(vcpu, VCPU_FTR_E_PT))
 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
 		else
 			vcpu->arch.eptcfg = 0;
 
+		/* Guest mmu emulation currently doesn't handle E.PT */
+		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
+		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1

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

* [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
emulation which is not supported yet. Configure TLBnCFG to remove E.PT
and E.HV.LRAT categories from VCPUs.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Remove E.HV.LRAT from vcpus

 arch/powerpc/kvm/e500_mmu.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index cf60db1..0d2a293 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
+
 		if (has_feature(vcpu, VCPU_FTR_E_PT))
 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
 		else
 			vcpu->arch.eptcfg = 0;
 
+		/* Guest mmu emulation currently doesn't handle E.PT */
+		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
+		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1

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

* [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
emulation which is not supported yet. Configure TLBnCFG to remove E.PT
and E.HV.LRAT categories from VCPUs.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Remove E.HV.LRAT from vcpus

 arch/powerpc/kvm/e500_mmu.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index cf60db1..0d2a293 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
+
 		if (has_feature(vcpu, VCPU_FTR_E_PT))
 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
 		else
 			vcpu->arch.eptcfg = 0;
 
+		/* Guest mmu emulation currently doesn't handle E.PT */
+		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
+		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1



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

* [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Extend processor compatibility names to e6500 cores.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
---
v2:
 - No change

 arch/powerpc/kvm/e500mc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index ab073a8..c3bdc0a 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -172,6 +172,8 @@ int kvmppc_core_check_processor_compat(void)
 		r = 0;
 	else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
 		r = 0;
+	else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0)
+		r = 0;
 	else
 		r = -ENOTSUPP;
 
-- 
1.7.4.1



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

* [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Extend processor compatibility names to e6500 cores.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
---
v2:
 - No change

 arch/powerpc/kvm/e500mc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index ab073a8..c3bdc0a 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -172,6 +172,8 @@ int kvmppc_core_check_processor_compat(void)
 		r = 0;
 	else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
 		r = 0;
+	else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0)
+		r = 0;
 	else
 		r = -ENOTSUPP;
 
-- 
1.7.4.1

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

* [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Extend processor compatibility names to e6500 cores.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
---
v2:
 - No change

 arch/powerpc/kvm/e500mc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index ab073a8..c3bdc0a 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -172,6 +172,8 @@ int kvmppc_core_check_processor_compat(void)
 		r = 0;
 	else if (strcmp(cur_cpu_spec->cpu_name, "e5500") = 0)
 		r = 0;
+	else if (strcmp(cur_cpu_spec->cpu_name, "e6500") = 0)
+		r = 0;
 	else
 		r = -ENOTSUPP;
 
-- 
1.7.4.1



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

* [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description
  2013-03-26 22:05 ` Mihai Caraman
  (?)
@ 2013-03-26 22:05   ` Mihai Caraman
  -1 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Add e6500 core to Kconfig description.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - New patch

 arch/powerpc/kvm/Kconfig |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 63c67ec..4489520 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -136,15 +136,15 @@ config KVM_E500V2
 	  If unsure, say N.
 
 config KVM_E500MC
-	bool "KVM support for PowerPC E500MC/E5500 processors"
+	bool "KVM support for PowerPC E500MC/E5500/E6500 processors"
 	depends on PPC_E500MC
 	select KVM
 	select KVM_MMIO
 	select KVM_BOOKE_HV
 	select MMU_NOTIFIER
 	---help---
-	  Support running unmodified E500MC/E5500 (32-bit) guest kernels in
-	  virtual machines on E500MC/E5500 host processors.
+	  Support running unmodified E500MC/E5500/E6500 guest kernels in
+	  virtual machines on E500MC/E5500/E6500 host processors.
 
 	  This module provides access to the hardware capabilities through
 	  a character device node named /dev/kvm.
-- 
1.7.4.1

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

* [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm

Add e6500 core to Kconfig description.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - New patch

 arch/powerpc/kvm/Kconfig |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 63c67ec..4489520 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -136,15 +136,15 @@ config KVM_E500V2
 	  If unsure, say N.
 
 config KVM_E500MC
-	bool "KVM support for PowerPC E500MC/E5500 processors"
+	bool "KVM support for PowerPC E500MC/E5500/E6500 processors"
 	depends on PPC_E500MC
 	select KVM
 	select KVM_MMIO
 	select KVM_BOOKE_HV
 	select MMU_NOTIFIER
 	---help---
-	  Support running unmodified E500MC/E5500 (32-bit) guest kernels in
-	  virtual machines on E500MC/E5500 host processors.
+	  Support running unmodified E500MC/E5500/E6500 guest kernels in
+	  virtual machines on E500MC/E5500/E6500 host processors.
 
 	  This module provides access to the hardware capabilities through
 	  a character device node named /dev/kvm.
-- 
1.7.4.1

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

* [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description
@ 2013-03-26 22:05   ` Mihai Caraman
  0 siblings, 0 replies; 43+ messages in thread
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: kvm, linuxppc-dev, Mihai Caraman

Add e6500 core to Kconfig description.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - New patch

 arch/powerpc/kvm/Kconfig |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 63c67ec..4489520 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -136,15 +136,15 @@ config KVM_E500V2
 	  If unsure, say N.
 
 config KVM_E500MC
-	bool "KVM support for PowerPC E500MC/E5500 processors"
+	bool "KVM support for PowerPC E500MC/E5500/E6500 processors"
 	depends on PPC_E500MC
 	select KVM
 	select KVM_MMIO
 	select KVM_BOOKE_HV
 	select MMU_NOTIFIER
 	---help---
-	  Support running unmodified E500MC/E5500 (32-bit) guest kernels in
-	  virtual machines on E500MC/E5500 host processors.
+	  Support running unmodified E500MC/E5500/E6500 guest kernels in
+	  virtual machines on E500MC/E5500/E6500 host processors.
 
 	  This module provides access to the hardware capabilities through
 	  a character device node named /dev/kvm.
-- 
1.7.4.1



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

* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-26 22:05   ` Mihai Caraman
@ 2013-03-26 22:42     ` Scott Wood
  -1 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-26 22:42 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, agraf

On 03/26/2013 05:05:06 PM, Mihai Caraman wrote:
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS1:
> +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS2:
> +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS7_3:
> +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS4:
> +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS6:
> +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> +		break;
> +	/* Only allow MMU registers to be set to the config supported  
> by KVM */
> +	case KVM_REG_PPC_MMUCFG: {
> +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> +			r = -EINVAL;
> +		break;
> +	}
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using  
> SW_TLB */
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> +			r = -EINVAL;
> +		break;
> +	}

Am I the only one that finds the set_reg_val/get_reg_val naming  
confusing?  At first glance it looks like it sets TLBnCFG and then  
later tests whether it should have. :-P

Functions should be named for what they do, not for what context you  
use them in.

-Scott

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

* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-26 22:42     ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-26 22:42 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, agraf

On 03/26/2013 05:05:06 PM, Mihai Caraman wrote:
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS1:
> +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS2:
> +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS7_3:
> +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS4:
> +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS6:
> +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> +		break;
> +	/* Only allow MMU registers to be set to the config supported  
> by KVM */
> +	case KVM_REG_PPC_MMUCFG: {
> +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> +			r = -EINVAL;
> +		break;
> +	}
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using  
> SW_TLB */
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> +			r = -EINVAL;
> +		break;
> +	}

Am I the only one that finds the set_reg_val/get_reg_val naming  
confusing?  At first glance it looks like it sets TLBnCFG and then  
later tests whether it should have. :-P

Functions should be named for what they do, not for what context you  
use them in.

-Scott

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

* Re: [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
  2013-03-26 22:05   ` Mihai Caraman
  (?)
@ 2013-03-26 22:48     ` Scott Wood
  -1 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-26 22:48 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc

On 03/26/2013 05:05:08 PM, Mihai Caraman wrote:
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index b73ca7a..795934d 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -23,6 +23,8 @@
>  #include <asm/mmu-book3e.h>
>  #include <asm/tlb.h>
> 
> +#define VCPU_FTR_MMU_V2		0

enum?  We don't care about the actual value here.

>  #define E500_PID_NUM   3
>  #define E500_TLB_NUM   2
> 
> @@ -299,4 +301,18 @@ static inline unsigned int  
> get_tlbmiss_tid(struct kvm_vcpu *vcpu)
>  #define get_tlb_sts(gtlbe)              (MAS1_TS)
>  #endif /* !BOOKE_HV */
> 
> +static inline bool has_feature(const struct kvm_vcpu *vcpu,
> +			       unsigned long vcpu_ftr)
> +{
> +	bool has_ftr;
> +	switch (vcpu_ftr) {
> +	case VCPU_FTR_MMU_V2:
> +		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) ==  
> MMUCFG_MAVN_V2);
> +		break;
> +	default:
> +		has_ftr = false;
> +	}
> +	return has_ftr;
> +}

vcpu_has_feature()

Can simplify by replacing has_ftr with "return true" and "return false".

-Scott

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

* Re: [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
@ 2013-03-26 22:48     ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-26 22:48 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc

On 03/26/2013 05:05:08 PM, Mihai Caraman wrote:
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index b73ca7a..795934d 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -23,6 +23,8 @@
>  #include <asm/mmu-book3e.h>
>  #include <asm/tlb.h>
>=20
> +#define VCPU_FTR_MMU_V2		0

enum?  We don't care about the actual value here.

>  #define E500_PID_NUM   3
>  #define E500_TLB_NUM   2
>=20
> @@ -299,4 +301,18 @@ static inline unsigned int =20
> get_tlbmiss_tid(struct kvm_vcpu *vcpu)
>  #define get_tlb_sts(gtlbe)              (MAS1_TS)
>  #endif /* !BOOKE_HV */
>=20
> +static inline bool has_feature(const struct kvm_vcpu *vcpu,
> +			       unsigned long vcpu_ftr)
> +{
> +	bool has_ftr;
> +	switch (vcpu_ftr) {
> +	case VCPU_FTR_MMU_V2:
> +		has_ftr =3D ((vcpu->arch.mmucfg & MMUCFG_MAVN) =3D=3D =20
> MMUCFG_MAVN_V2);
> +		break;
> +	default:
> +		has_ftr =3D false;
> +	}
> +	return has_ftr;
> +}

vcpu_has_feature()

Can simplify by replacing has_ftr with "return true" and "return false".

-Scott=

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

* Re: [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers
@ 2013-03-26 22:48     ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-26 22:48 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc

On 03/26/2013 05:05:08 PM, Mihai Caraman wrote:
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index b73ca7a..795934d 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -23,6 +23,8 @@
>  #include <asm/mmu-book3e.h>
>  #include <asm/tlb.h>
> 
> +#define VCPU_FTR_MMU_V2		0

enum?  We don't care about the actual value here.

>  #define E500_PID_NUM   3
>  #define E500_TLB_NUM   2
> 
> @@ -299,4 +301,18 @@ static inline unsigned int  
> get_tlbmiss_tid(struct kvm_vcpu *vcpu)
>  #define get_tlb_sts(gtlbe)              (MAS1_TS)
>  #endif /* !BOOKE_HV */
> 
> +static inline bool has_feature(const struct kvm_vcpu *vcpu,
> +			       unsigned long vcpu_ftr)
> +{
> +	bool has_ftr;
> +	switch (vcpu_ftr) {
> +	case VCPU_FTR_MMU_V2:
> +		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) =  
> MMUCFG_MAVN_V2);
> +		break;
> +	default:
> +		has_ftr = false;
> +	}
> +	return has_ftr;
> +}

vcpu_has_feature()

Can simplify by replacing has_ftr with "return true" and "return false".

-Scott

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

* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-26 22:05   ` Mihai Caraman
  (?)
@ 2013-03-27 15:58     ` Alexander Graf
  -1 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 15:58 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> MMU registers were exposed to user-space using sregs interface. Add them
> to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg delegation
> interface introduced by book3s.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Restrict set_one_reg operation for MMU registers to HW values
> 
> Documentation/virtual/kvm/api.txt   |   11 +++++
> arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
> arch/powerpc/kvm/44x.c              |   12 +++++
> arch/powerpc/kvm/booke.c            |   83 ++++++++++++++++++++--------------
> arch/powerpc/kvm/e500.c             |   14 ++++++
> arch/powerpc/kvm/e500.h             |    4 ++
> arch/powerpc/kvm/e500_mmu.c         |   84 +++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/e500mc.c           |   14 ++++++
> 8 files changed, 205 insertions(+), 34 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 976eb65..1a76663 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1792,6 +1792,17 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TSR	| 32
>   PPC   | KVM_REG_PPC_OR_TSR	| 32
>   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
> +  PPC   | KVM_REG_PPC_MAS0	| 32
> +  PPC   | KVM_REG_PPC_MAS1	| 32
> +  PPC   | KVM_REG_PPC_MAS2	| 64
> +  PPC   | KVM_REG_PPC_MAS7_3	| 64
> +  PPC   | KVM_REG_PPC_MAS4	| 32
> +  PPC   | KVM_REG_PPC_MAS6	| 32
> +  PPC   | KVM_REG_PPC_MMUCFG	| 32
> +  PPC   | KVM_REG_PPC_TLB0CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB1CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB2CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB3CFG	| 32
> 
> ARM registers are mapped using the lower 32 bits.  The upper 16 of that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index ef072b1..777dc81 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -422,4 +422,21 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
> #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
> #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
> +
> +/* MMU registers */
> +#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
> +#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
> +#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
> +#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
> +#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
> +#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
> +#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
> +/*
> + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
> + * KVM_CAP_SW_TLB ioctl
> + */
> +#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
> +#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
> +#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
> +#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..2f5c6b6 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_44x *vcpu_44x;
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 58057d6..c67e99f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
> 
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	int r = -EINVAL;
> +	int r = 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size = one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
> 
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac = reg->id - KVM_REG_PPC_IAC1;
> -		r = copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.iac[iac], sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_IAC1;
> +		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);

Please split this into a separate patch. You're merely cleaning up existing code here, not adding new functionality as the patch description says.

> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac = reg->id - KVM_REG_PPC_DAC1;
> -		r = copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_DAC1;
> +		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> 		u32 epr = get_guest_epr(vcpu);
> -		r = put_user(epr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR:
> -		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.epcr);
> 		break;
> #endif
> 	case KVM_REG_PPC_TCR:
> -		r = put_user(vcpu->arch.tcr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.tcr);
> 		break;
> 	case KVM_REG_PPC_TSR:
> -		r = put_user(vcpu->arch.tsr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.tsr);
> 		break;
> 	default:
> +		r = kvmppc_get_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> +	if (r)
> +		return r;
> +
> +	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
> +		r = -EFAULT;
> +
> 	return r;
> }
> 
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	int r = -EINVAL;
> +	int r = 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size = one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
> +
> +	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
> +		return -EFAULT;
> 
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac = reg->id - KVM_REG_PPC_IAC1;
> -		r = copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
> -			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_IAC1;
> +		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac = reg->id - KVM_REG_PPC_DAC1;
> -		r = copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
> -			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_DAC1;
> +		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> -		u32 new_epr;
> -		r = get_user(new_epr, (u32 __user *)(long)reg->addr);
> -		if (!r)
> -			kvmppc_set_epr(vcpu, new_epr);
> +		u32 new_epr = set_reg_val(reg->id, val);
> +		kvmppc_set_epr(vcpu, new_epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR: {
> -		u32 new_epcr;
> -		r = get_user(new_epcr, (u32 __user *)(long)reg->addr);
> -		if (r == 0)
> -			kvmppc_set_epcr(vcpu, new_epcr);
> +		u32 new_epcr = set_reg_val(reg->id, val);
> +		kvmppc_set_epcr(vcpu, new_epcr);

What about the sanity check?

> 		break;
> 	}
> #endif
> 	case KVM_REG_PPC_OR_TSR: {
> -		u32 tsr_bits;
> -		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits = set_reg_val(reg->id, val);
> 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_CLEAR_TSR: {
> -		u32 tsr_bits;
> -		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits = set_reg_val(reg->id, val);
> 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_TSR: {
> -		u32 tsr;
> -		r = get_user(tsr, (u32 __user *)(long)reg->addr);
> +		u32 tsr = set_reg_val(reg->id, val);
> 		kvmppc_set_tsr(vcpu, tsr);
> 		break;
> 	}
> 	case KVM_REG_PPC_TCR: {
> -		u32 tcr;
> -		r = get_user(tcr, (u32 __user *)(long)reg->addr);
> +		u32 tcr = set_reg_val(reg->id, val);
> 		kvmppc_set_tcr(vcpu, tcr);
> 		break;
> 	}
> 	default:
> +		r = kvmppc_set_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> 	return r;
> }
> 
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..ce6b73c 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 33db48a..b73ca7a 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> 
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val);
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val);
> 
> #ifdef CONFIG_KVM_E500V2
> unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 5c44759..68c2b00 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return 0;
> }
> 
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas0);

Missing breaks?


Alex

> +	case KVM_REG_PPC_MAS1:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas1);
> +	case KVM_REG_PPC_MAS2:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas2);
> +	case KVM_REG_PPC_MAS7_3:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
> +	case KVM_REG_PPC_MAS4:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas4);
> +	case KVM_REG_PPC_MAS6:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas6);
> +	case KVM_REG_PPC_MMUCFG:
> +		*val = get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG:
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
> +	default:
> +		r = -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS1:
> +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS2:
> +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS7_3:
> +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS4:
> +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS6:
> +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> +		break;
> +	/* Only allow MMU registers to be set to the config supported by KVM */
> +	case KVM_REG_PPC_MMUCFG: {
> +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> +			r = -EINVAL;
> +		break;
> +	}
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> +			r = -EINVAL;
> +		break;
> +	}
> +	default:
> +		r = -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
> 			      struct kvm_config_tlb *cfg)
> {
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..ab073a8 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-27 15:58     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 15:58 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> MMU registers were exposed to user-space using sregs interface. Add =
them
> to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg =
delegation
> interface introduced by book3s.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Restrict set_one_reg operation for MMU registers to HW values
>=20
> Documentation/virtual/kvm/api.txt   |   11 +++++
> arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
> arch/powerpc/kvm/44x.c              |   12 +++++
> arch/powerpc/kvm/booke.c            |   83 =
++++++++++++++++++++--------------
> arch/powerpc/kvm/e500.c             |   14 ++++++
> arch/powerpc/kvm/e500.h             |    4 ++
> arch/powerpc/kvm/e500_mmu.c         |   84 =
+++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/e500mc.c           |   14 ++++++
> 8 files changed, 205 insertions(+), 34 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index 976eb65..1a76663 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1792,6 +1792,17 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TSR	| 32
>   PPC   | KVM_REG_PPC_OR_TSR	| 32
>   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
> +  PPC   | KVM_REG_PPC_MAS0	| 32
> +  PPC   | KVM_REG_PPC_MAS1	| 32
> +  PPC   | KVM_REG_PPC_MAS2	| 64
> +  PPC   | KVM_REG_PPC_MAS7_3	| 64
> +  PPC   | KVM_REG_PPC_MAS4	| 32
> +  PPC   | KVM_REG_PPC_MAS6	| 32
> +  PPC   | KVM_REG_PPC_MMUCFG	| 32
> +  PPC   | KVM_REG_PPC_TLB0CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB1CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB2CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB3CFG	| 32
>=20
> ARM registers are mapped using the lower 32 bits.  The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index ef072b1..777dc81 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -422,4 +422,21 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
> #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x89)
> #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x8a)
> +
> +/* MMU registers */
> +#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
> +#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
> +#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
> +#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
> +#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
> +#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
> +#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
> +/*
> + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed =
only using
> + * KVM_CAP_SW_TLB ioctl
> + */
> +#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
> +#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
> +#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
> +#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..2f5c6b6 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> 	struct kvmppc_vcpu_44x *vcpu_44x;
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 58057d6..c67e99f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct =
kvm_vcpu *vcpu,
>=20
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> -	int r =3D -EINVAL;
> +	int r =3D 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size =3D one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
>=20
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac =3D reg->id - KVM_REG_PPC_IAC1;
> -		r =3D copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.iac[iac], =
sizeof(u64));
> +		i =3D reg->id - KVM_REG_PPC_IAC1;
> +		val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);

Please split this into a separate patch. You're merely cleaning up =
existing code here, not adding new functionality as the patch =
description says.

> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac =3D reg->id - KVM_REG_PPC_DAC1;
> -		r =3D copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.dac[dac], =
sizeof(u64));
> +		i =3D reg->id - KVM_REG_PPC_DAC1;
> +		val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> 		u32 epr =3D get_guest_epr(vcpu);
> -		r =3D put_user(epr, (u32 __user *)(long)reg->addr);
> +		val =3D get_reg_val(reg->id, epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR:
> -		r =3D put_user(vcpu->arch.epcr, (u32 __user =
*)(long)reg->addr);
> +		val =3D get_reg_val(reg->id, vcpu->arch.epcr);
> 		break;
> #endif
> 	case KVM_REG_PPC_TCR:
> -		r =3D put_user(vcpu->arch.tcr, (u32 __user =
*)(long)reg->addr);
> +		val =3D get_reg_val(reg->id, vcpu->arch.tcr);
> 		break;
> 	case KVM_REG_PPC_TSR:
> -		r =3D put_user(vcpu->arch.tsr, (u32 __user =
*)(long)reg->addr);
> +		val =3D get_reg_val(reg->id, vcpu->arch.tsr);
> 		break;
> 	default:
> +		r =3D kvmppc_get_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> +	if (r)
> +		return r;
> +
> +	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, =
size))
> +		r =3D -EFAULT;
> +
> 	return r;
> }
>=20
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> -	int r =3D -EINVAL;
> +	int r =3D 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size =3D one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
> +
> +	if (copy_from_user(&val, (char __user *)(unsigned =
long)reg->addr, size))
> +		return -EFAULT;
>=20
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac =3D reg->id - KVM_REG_PPC_IAC1;
> -		r =3D copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
> -			     (u64 __user *)(long)reg->addr, =
sizeof(u64));
> +		i =3D reg->id - KVM_REG_PPC_IAC1;
> +		vcpu->arch.dbg_reg.iac[i] =3D set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac =3D reg->id - KVM_REG_PPC_DAC1;
> -		r =3D copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
> -			     (u64 __user *)(long)reg->addr, =
sizeof(u64));
> +		i =3D reg->id - KVM_REG_PPC_DAC1;
> +		vcpu->arch.dbg_reg.dac[i] =3D set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> -		u32 new_epr;
> -		r =3D get_user(new_epr, (u32 __user *)(long)reg->addr);
> -		if (!r)
> -			kvmppc_set_epr(vcpu, new_epr);
> +		u32 new_epr =3D set_reg_val(reg->id, val);
> +		kvmppc_set_epr(vcpu, new_epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR: {
> -		u32 new_epcr;
> -		r =3D get_user(new_epcr, (u32 __user *)(long)reg->addr);
> -		if (r =3D=3D 0)
> -			kvmppc_set_epcr(vcpu, new_epcr);
> +		u32 new_epcr =3D set_reg_val(reg->id, val);
> +		kvmppc_set_epcr(vcpu, new_epcr);

What about the sanity check?

> 		break;
> 	}
> #endif
> 	case KVM_REG_PPC_OR_TSR: {
> -		u32 tsr_bits;
> -		r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits =3D set_reg_val(reg->id, val);
> 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_CLEAR_TSR: {
> -		u32 tsr_bits;
> -		r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits =3D set_reg_val(reg->id, val);
> 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_TSR: {
> -		u32 tsr;
> -		r =3D get_user(tsr, (u32 __user *)(long)reg->addr);
> +		u32 tsr =3D set_reg_val(reg->id, val);
> 		kvmppc_set_tsr(vcpu, tsr);
> 		break;
> 	}
> 	case KVM_REG_PPC_TCR: {
> -		u32 tcr;
> -		r =3D get_user(tcr, (u32 __user *)(long)reg->addr);
> +		u32 tcr =3D set_reg_val(reg->id, val);
> 		kvmppc_set_tcr(vcpu, tcr);
> 		break;
> 	}
> 	default:
> +		r =3D kvmppc_set_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> 	return r;
> }
>=20
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..ce6b73c 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 33db48a..b73ca7a 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct =
kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
> int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val);
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val);
>=20
> #ifdef CONFIG_KVM_E500V2
> unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 5c44759..68c2b00 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu =
*vcpu, struct kvm_sregs *sregs)
> 	return 0;
> }
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val)
> +{
> +	int r =3D 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas0);

Missing breaks?


Alex

> +	case KVM_REG_PPC_MAS1:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas1);
> +	case KVM_REG_PPC_MAS2:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas2);
> +	case KVM_REG_PPC_MAS7_3:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas7_3);
> +	case KVM_REG_PPC_MAS4:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas4);
> +	case KVM_REG_PPC_MAS6:
> +		*val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> +	case KVM_REG_PPC_MMUCFG:
> +		*val =3D get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG:
> +		i =3D id - KVM_REG_PPC_TLB0CFG;
> +		*val =3D get_reg_val(id, vcpu->arch.tlbcfg[i]);
> +	default:
> +		r =3D -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val)
> +{
> +	int r =3D 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		vcpu->arch.shared->mas0 =3D set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS1:
> +		vcpu->arch.shared->mas1 =3D set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS2:
> +		vcpu->arch.shared->mas2 =3D set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS7_3:
> +		vcpu->arch.shared->mas7_3 =3D set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS4:
> +		vcpu->arch.shared->mas4 =3D set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS6:
> +		vcpu->arch.shared->mas6 =3D set_reg_val(id, *val);
> +		break;
> +	/* Only allow MMU registers to be set to the config supported by =
KVM */
> +	case KVM_REG_PPC_MMUCFG: {
> +		if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
> +			r =3D -EINVAL;
> +		break;
> +	}
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using =
SW_TLB */
> +		i =3D id - KVM_REG_PPC_TLB0CFG;
> +		if (set_reg_val(id, *val) !=3D vcpu->arch.tlbcfg[i])
> +			r =3D -EINVAL;
> +		break;
> +	}
> +	default:
> +		r =3D -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
> 			      struct kvm_config_tlb *cfg)
> {
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..ab073a8 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r =3D kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-27 15:58     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 15:58 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> MMU registers were exposed to user-space using sregs interface. Add them
> to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg delegation
> interface introduced by book3s.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Restrict set_one_reg operation for MMU registers to HW values
> 
> Documentation/virtual/kvm/api.txt   |   11 +++++
> arch/powerpc/include/uapi/asm/kvm.h |   17 +++++++
> arch/powerpc/kvm/44x.c              |   12 +++++
> arch/powerpc/kvm/booke.c            |   83 ++++++++++++++++++++--------------
> arch/powerpc/kvm/e500.c             |   14 ++++++
> arch/powerpc/kvm/e500.h             |    4 ++
> arch/powerpc/kvm/e500_mmu.c         |   84 +++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/e500mc.c           |   14 ++++++
> 8 files changed, 205 insertions(+), 34 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 976eb65..1a76663 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1792,6 +1792,17 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TSR	| 32
>   PPC   | KVM_REG_PPC_OR_TSR	| 32
>   PPC   | KVM_REG_PPC_CLEAR_TSR	| 32
> +  PPC   | KVM_REG_PPC_MAS0	| 32
> +  PPC   | KVM_REG_PPC_MAS1	| 32
> +  PPC   | KVM_REG_PPC_MAS2	| 64
> +  PPC   | KVM_REG_PPC_MAS7_3	| 64
> +  PPC   | KVM_REG_PPC_MAS4	| 32
> +  PPC   | KVM_REG_PPC_MAS6	| 32
> +  PPC   | KVM_REG_PPC_MMUCFG	| 32
> +  PPC   | KVM_REG_PPC_TLB0CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB1CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB2CFG	| 32
> +  PPC   | KVM_REG_PPC_TLB3CFG	| 32
> 
> ARM registers are mapped using the lower 32 bits.  The upper 16 of that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index ef072b1..777dc81 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -422,4 +422,21 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
> #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
> #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
> +
> +/* MMU registers */
> +#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
> +#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
> +#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
> +#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
> +#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
> +#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
> +#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
> +/*
> + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
> + * KVM_CAP_SW_TLB ioctl
> + */
> +#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
> +#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
> +#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
> +#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..2f5c6b6 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	return -EINVAL;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_44x *vcpu_44x;
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 58057d6..c67e99f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
> 
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	int r = -EINVAL;
> +	int r = 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size = one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
> 
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac = reg->id - KVM_REG_PPC_IAC1;
> -		r = copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.iac[iac], sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_IAC1;
> +		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);

Please split this into a separate patch. You're merely cleaning up existing code here, not adding new functionality as the patch description says.

> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac = reg->id - KVM_REG_PPC_DAC1;
> -		r = copy_to_user((u64 __user *)(long)reg->addr,
> -				 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_DAC1;
> +		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> 		u32 epr = get_guest_epr(vcpu);
> -		r = put_user(epr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR:
> -		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.epcr);
> 		break;
> #endif
> 	case KVM_REG_PPC_TCR:
> -		r = put_user(vcpu->arch.tcr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.tcr);
> 		break;
> 	case KVM_REG_PPC_TSR:
> -		r = put_user(vcpu->arch.tsr, (u32 __user *)(long)reg->addr);
> +		val = get_reg_val(reg->id, vcpu->arch.tsr);
> 		break;
> 	default:
> +		r = kvmppc_get_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> +	if (r)
> +		return r;
> +
> +	if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
> +		r = -EFAULT;
> +
> 	return r;
> }
> 
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> {
> -	int r = -EINVAL;
> +	int r = 0;
> +	union kvmppc_one_reg val;
> +	int size;
> +	long int i;
> +
> +	size = one_reg_size(reg->id);
> +	if (size > sizeof(val))
> +		return -EINVAL;
> +
> +	if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
> +		return -EFAULT;
> 
> 	switch (reg->id) {
> 	case KVM_REG_PPC_IAC1:
> 	case KVM_REG_PPC_IAC2:
> 	case KVM_REG_PPC_IAC3:
> 	case KVM_REG_PPC_IAC4: {
> -		int iac = reg->id - KVM_REG_PPC_IAC1;
> -		r = copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
> -			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_IAC1;
> +		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_DAC1:
> 	case KVM_REG_PPC_DAC2: {
> -		int dac = reg->id - KVM_REG_PPC_DAC1;
> -		r = copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
> -			     (u64 __user *)(long)reg->addr, sizeof(u64));
> +		i = reg->id - KVM_REG_PPC_DAC1;
> +		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
> 		break;
> 	}
> 	case KVM_REG_PPC_EPR: {
> -		u32 new_epr;
> -		r = get_user(new_epr, (u32 __user *)(long)reg->addr);
> -		if (!r)
> -			kvmppc_set_epr(vcpu, new_epr);
> +		u32 new_epr = set_reg_val(reg->id, val);
> +		kvmppc_set_epr(vcpu, new_epr);
> 		break;
> 	}
> #if defined(CONFIG_64BIT)
> 	case KVM_REG_PPC_EPCR: {
> -		u32 new_epcr;
> -		r = get_user(new_epcr, (u32 __user *)(long)reg->addr);
> -		if (r = 0)
> -			kvmppc_set_epcr(vcpu, new_epcr);
> +		u32 new_epcr = set_reg_val(reg->id, val);
> +		kvmppc_set_epcr(vcpu, new_epcr);

What about the sanity check?

> 		break;
> 	}
> #endif
> 	case KVM_REG_PPC_OR_TSR: {
> -		u32 tsr_bits;
> -		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits = set_reg_val(reg->id, val);
> 		kvmppc_set_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_CLEAR_TSR: {
> -		u32 tsr_bits;
> -		r = get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> +		u32 tsr_bits = set_reg_val(reg->id, val);
> 		kvmppc_clr_tsr_bits(vcpu, tsr_bits);
> 		break;
> 	}
> 	case KVM_REG_PPC_TSR: {
> -		u32 tsr;
> -		r = get_user(tsr, (u32 __user *)(long)reg->addr);
> +		u32 tsr = set_reg_val(reg->id, val);
> 		kvmppc_set_tsr(vcpu, tsr);
> 		break;
> 	}
> 	case KVM_REG_PPC_TCR: {
> -		u32 tcr;
> -		r = get_user(tcr, (u32 __user *)(long)reg->addr);
> +		u32 tcr = set_reg_val(reg->id, val);
> 		kvmppc_set_tcr(vcpu, tcr);
> 		break;
> 	}
> 	default:
> +		r = kvmppc_set_one_reg(vcpu, reg->id, &val);
> 		break;
> 	}
> +
> 	return r;
> }
> 
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..ce6b73c 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 33db48a..b73ca7a 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> 
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val);
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val);
> 
> #ifdef CONFIG_KVM_E500V2
> unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 5c44759..68c2b00 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return 0;
> }
> 
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas0);

Missing breaks?


Alex

> +	case KVM_REG_PPC_MAS1:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas1);
> +	case KVM_REG_PPC_MAS2:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas2);
> +	case KVM_REG_PPC_MAS7_3:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
> +	case KVM_REG_PPC_MAS4:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas4);
> +	case KVM_REG_PPC_MAS6:
> +		*val = get_reg_val(id, vcpu->arch.shared->mas6);
> +	case KVM_REG_PPC_MMUCFG:
> +		*val = get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG:
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		*val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
> +	default:
> +		r = -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +			       union kvmppc_one_reg *val)
> +{
> +	int r = 0;
> +	long int i;
> +
> +	switch (id) {
> +	case KVM_REG_PPC_MAS0:
> +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS1:
> +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS2:
> +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS7_3:
> +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS4:
> +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> +		break;
> +	case KVM_REG_PPC_MAS6:
> +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> +		break;
> +	/* Only allow MMU registers to be set to the config supported by KVM */
> +	case KVM_REG_PPC_MMUCFG: {
> +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> +			r = -EINVAL;
> +		break;
> +	}
> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
> +		i = id - KVM_REG_PPC_TLB0CFG;
> +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> +			r = -EINVAL;
> +		break;
> +	}
> +	default:
> +		r = -EINVAL;
> +		break;
> +	}
> +
> +	return r;
> +}
> +
> int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
> 			      struct kvm_config_tlb *cfg)
> {
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..ab073a8 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +			union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> +		       union kvmppc_one_reg *val)
> +{
> +	int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
> +	return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500;
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
  2013-03-26 22:05   ` Mihai Caraman
  (?)
@ 2013-03-27 17:21     ` Alexander Graf
  -1 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:21 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
> in the presence of MAV 2.0. Support it now.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Use has_feature() function
> 
> Documentation/virtual/kvm/api.txt   |    1 +
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/include/uapi/asm/kvm.h |    1 +
> arch/powerpc/kvm/e500.h             |    5 +++++
> arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
> arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
> 6 files changed, 28 insertions(+), 0 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index f045377..a1f2200 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1807,6 +1807,7 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TLB1PS	| 32
>   PPC   | KVM_REG_PPC_TLB2PS	| 32
>   PPC   | KVM_REG_PPC_TLB3PS	| 32
> +  PPC   | KVM_REG_PPC_EPTCFG	| 32
> 
> ARM registers are mapped using the lower 32 bits.  The upper 16 of that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 3b6cee3..8a48e68 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 tlbps[4];
> 	u32 mmucfg;
> +	u32 eptcfg;
> 	u32 epr;
> 	u32 crit_save;
> 	struct kvmppc_booke_debug_reg dbg_reg;
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index 7cfd13f..9d7fbf0 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -443,4 +443,5 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
> #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
> #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
> +#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 795934d..6cfc669 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -24,6 +24,7 @@
> #include <asm/tlb.h>
> 
> #define VCPU_FTR_MMU_V2		0
> +#define VCPU_FTR_E_PT		1
> 
> #define E500_PID_NUM   3
> #define E500_TLB_NUM   2
> @@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
> 	case VCPU_FTR_MMU_V2:
> 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
> 		break;
> +	case VCPU_FTR_E_PT:
> +		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
> +			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
> +		break;
> 	default:
> 		has_ftr = false;
> 	}
> diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
> index 12b8de2..b10a012 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
> 	case SPRN_MMUCFG:
> 		*spr_val = vcpu->arch.mmucfg;
> 		break;
> +	case SPRN_EPTCFG:
> +		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
> +			return EMULATE_FAIL;
> +		/*
> +		 * Legacy Linux guests access EPTCFG register even if the E.PT
> +		 * category is disabled in the VM. Give them a chance to live.
> +		 */
> +		*spr_val = vcpu->arch.eptcfg;
> +		break;
> 
> 	/* extra exceptions */
> 	case SPRN_IVOR32:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index e354fa1..cf60db1 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
> 	case KVM_REG_PPC_MMUCFG:
> 		*val = get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_EPTCFG:
> +		*val = get_reg_val(id, vcpu->arch.eptcfg);
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> 			r = -EINVAL;
> 		break;
> 	}
> +	case KVM_REG_PPC_EPTCFG:
> +		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
> +			r = -EINVAL;
> +		break;
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		if (has_feature(vcpu, VCPU_FTR_E_PT))
> +			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);

Can't we just always set it to 0?


Alex

> +		else
> +			vcpu->arch.eptcfg = 0;
> +
> 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
> 	}
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
@ 2013-03-27 17:21     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:21 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> EPTCFG register defined by E.PT is accessed unconditionally by Linux =
guests
> in the presence of MAV 2.0. Support it now.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Use has_feature() function
>=20
> Documentation/virtual/kvm/api.txt   |    1 +
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/include/uapi/asm/kvm.h |    1 +
> arch/powerpc/kvm/e500.h             |    5 +++++
> arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
> arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
> 6 files changed, 28 insertions(+), 0 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index f045377..a1f2200 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1807,6 +1807,7 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TLB1PS	| 32
>   PPC   | KVM_REG_PPC_TLB2PS	| 32
>   PPC   | KVM_REG_PPC_TLB3PS	| 32
> +  PPC   | KVM_REG_PPC_EPTCFG	| 32
>=20
> ARM registers are mapped using the lower 32 bits.  The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/asm/kvm_host.h =
b/arch/powerpc/include/asm/kvm_host.h
> index 3b6cee3..8a48e68 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 tlbps[4];
> 	u32 mmucfg;
> +	u32 eptcfg;
> 	u32 epr;
> 	u32 crit_save;
> 	struct kvmppc_booke_debug_reg dbg_reg;
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index 7cfd13f..9d7fbf0 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -443,4 +443,5 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
> #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
> #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
> +#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 795934d..6cfc669 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -24,6 +24,7 @@
> #include <asm/tlb.h>
>=20
> #define VCPU_FTR_MMU_V2		0
> +#define VCPU_FTR_E_PT		1
>=20
> #define E500_PID_NUM   3
> #define E500_TLB_NUM   2
> @@ -309,6 +310,10 @@ static inline bool has_feature(const struct =
kvm_vcpu *vcpu,
> 	case VCPU_FTR_MMU_V2:
> 		has_ftr =3D ((vcpu->arch.mmucfg & MMUCFG_MAVN) =3D=3D =
MMUCFG_MAVN_V2);
> 		break;
> +	case VCPU_FTR_E_PT:
> +		has_ftr =3D ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
> +			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
> +		break;
> 	default:
> 		has_ftr =3D false;
> 	}
> diff --git a/arch/powerpc/kvm/e500_emulate.c =
b/arch/powerpc/kvm/e500_emulate.c
> index 12b8de2..b10a012 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu =
*vcpu, int sprn, ulong *spr_val)
> 	case SPRN_MMUCFG:
> 		*spr_val =3D vcpu->arch.mmucfg;
> 		break;
> +	case SPRN_EPTCFG:
> +		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
> +			return EMULATE_FAIL;
> +		/*
> +		 * Legacy Linux guests access EPTCFG register even if =
the E.PT
> +		 * category is disabled in the VM. Give them a chance to =
live.
> +		 */
> +		*spr_val =3D vcpu->arch.eptcfg;
> +		break;
>=20
> 	/* extra exceptions */
> 	case SPRN_IVOR32:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index e354fa1..cf60db1 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> 		*val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> 	case KVM_REG_PPC_MMUCFG:
> 		*val =3D get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_EPTCFG:
> +		*val =3D get_reg_val(id, vcpu->arch.eptcfg);
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> 			r =3D -EINVAL;
> 		break;
> 	}
> +	case KVM_REG_PPC_EPTCFG:
> +		if (set_reg_val(id, *val) !=3D vcpu->arch.eptcfg)
> +			r =3D -EINVAL;
> +		break;
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		if (has_feature(vcpu, VCPU_FTR_E_PT))
> +			vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);

Can't we just always set it to 0?


Alex

> +		else
> +			vcpu->arch.eptcfg =3D 0;
> +
> 		vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> 	}
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
@ 2013-03-27 17:21     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:21 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
> in the presence of MAV 2.0. Support it now.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Use has_feature() function
> 
> Documentation/virtual/kvm/api.txt   |    1 +
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/include/uapi/asm/kvm.h |    1 +
> arch/powerpc/kvm/e500.h             |    5 +++++
> arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
> arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
> 6 files changed, 28 insertions(+), 0 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index f045377..a1f2200 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1807,6 +1807,7 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_TLB1PS	| 32
>   PPC   | KVM_REG_PPC_TLB2PS	| 32
>   PPC   | KVM_REG_PPC_TLB3PS	| 32
> +  PPC   | KVM_REG_PPC_EPTCFG	| 32
> 
> ARM registers are mapped using the lower 32 bits.  The upper 16 of that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 3b6cee3..8a48e68 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 tlbps[4];
> 	u32 mmucfg;
> +	u32 eptcfg;
> 	u32 epr;
> 	u32 crit_save;
> 	struct kvmppc_booke_debug_reg dbg_reg;
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index 7cfd13f..9d7fbf0 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -443,4 +443,5 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
> #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
> #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
> +#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 795934d..6cfc669 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -24,6 +24,7 @@
> #include <asm/tlb.h>
> 
> #define VCPU_FTR_MMU_V2		0
> +#define VCPU_FTR_E_PT		1
> 
> #define E500_PID_NUM   3
> #define E500_TLB_NUM   2
> @@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
> 	case VCPU_FTR_MMU_V2:
> 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) = MMUCFG_MAVN_V2);
> 		break;
> +	case VCPU_FTR_E_PT:
> +		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
> +			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
> +		break;
> 	default:
> 		has_ftr = false;
> 	}
> diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
> index 12b8de2..b10a012 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
> 	case SPRN_MMUCFG:
> 		*spr_val = vcpu->arch.mmucfg;
> 		break;
> +	case SPRN_EPTCFG:
> +		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
> +			return EMULATE_FAIL;
> +		/*
> +		 * Legacy Linux guests access EPTCFG register even if the E.PT
> +		 * category is disabled in the VM. Give them a chance to live.
> +		 */
> +		*spr_val = vcpu->arch.eptcfg;
> +		break;
> 
> 	/* extra exceptions */
> 	case SPRN_IVOR32:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index e354fa1..cf60db1 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
> 	case KVM_REG_PPC_MMUCFG:
> 		*val = get_reg_val(id, vcpu->arch.mmucfg);
> +	case KVM_REG_PPC_EPTCFG:
> +		*val = get_reg_val(id, vcpu->arch.eptcfg);
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> 			r = -EINVAL;
> 		break;
> 	}
> +	case KVM_REG_PPC_EPTCFG:
> +		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
> +			r = -EINVAL;
> +		break;
> 	case KVM_REG_PPC_TLB0CFG:
> 	case KVM_REG_PPC_TLB1CFG:
> 	case KVM_REG_PPC_TLB2CFG:
> @@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		if (has_feature(vcpu, VCPU_FTR_E_PT))
> +			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);

Can't we just always set it to 0?


Alex

> +		else
> +			vcpu->arch.eptcfg = 0;
> +
> 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
> 	}
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  2013-03-26 22:05   ` Mihai Caraman
  (?)
@ 2013-03-27 17:23     ` Alexander Graf
  -1 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:23 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
> 
> arch/powerpc/kvm/e500_mmu.c |    6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
> +
> 		if (has_feature(vcpu, VCPU_FTR_E_PT))
> 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
> 		else
> 			vcpu->arch.eptcfg = 0;
> 
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;

Can we make this conditional on bits in EPTCFG? Then by initializing it to 0 today, we always mask PT/IND out, but later when we support EPT, we only have to set the bit in EPTCFG and everyone's happy?


Alex

> +
> 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
> 	}
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-27 17:23     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:23 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =
entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
>=20
> arch/powerpc/kvm/e500_mmu.c |    6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
> 		if (has_feature(vcpu, VCPU_FTR_E_PT))
> 			vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
> 		else
> 			vcpu->arch.eptcfg =3D 0;
>=20
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;

Can we make this conditional on bits in EPTCFG? Then by initializing it =
to 0 today, we always mask PT/IND out, but later when we support EPT, we =
only have to set the bit in EPTCFG and everyone's happy?


Alex

> +
> 		vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> 	}
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-27 17:23     ` Alexander Graf
  0 siblings, 0 replies; 43+ messages in thread
From: Alexander Graf @ 2013-03-27 17:23 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev


On 26.03.2013, at 23:05, Mihai Caraman wrote:

> Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
> 
> arch/powerpc/kvm/e500_mmu.c |    6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
> 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
> +
> 		if (has_feature(vcpu, VCPU_FTR_E_PT))
> 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
> 		else
> 			vcpu->arch.eptcfg = 0;
> 
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;

Can we make this conditional on bits in EPTCFG? Then by initializing it to 0 today, we always mask PT/IND out, but later when we support EPT, we only have to set the bit in EPTCFG and everyone's happy?


Alex

> +
> 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
> 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
> 	}
> -- 
> 1.7.4.1
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
  2013-03-26 22:05   ` Mihai Caraman
  (?)
@ 2013-03-27 17:50     ` Scott Wood
  -1 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-27 17:50 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev, Mihai Caraman

On 03/26/2013 05:05:10 PM, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb  
> entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
>  - Remove E.HV.LRAT from vcpus
> 
>  arch/powerpc/kvm/e500_mmu.c |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
>  	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
>  	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
> +
>  		if (has_feature(vcpu, VCPU_FTR_E_PT))
>  			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
>  		else
>  			vcpu->arch.eptcfg = 0;
> 
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;

You're clearing these bits *after* calling has_feature() -- doesn't  
has_feature() depend on those bits being cleared to not advertise E_PT  
support?

-Scott

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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-27 17:50     ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-27 17:50 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc

On 03/26/2013 05:05:10 PM, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =20
> entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
>  - Remove E.HV.LRAT from vcpus
>=20
>  arch/powerpc/kvm/e500_mmu.c |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
>  	vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
>  	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
>  		if (has_feature(vcpu, VCPU_FTR_E_PT))
>  			vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
>  		else
>  			vcpu->arch.eptcfg =3D 0;
>=20
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;

You're clearing these bits *after* calling has_feature() -- doesn't =20
has_feature() depend on those bits being cleared to not advertise E_PT =20
support?

-Scott=

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

* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
@ 2013-03-27 17:50     ` Scott Wood
  0 siblings, 0 replies; 43+ messages in thread
From: Scott Wood @ 2013-03-27 17:50 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: kvm-ppc, kvm, linuxppc-dev, Mihai Caraman

On 03/26/2013 05:05:10 PM, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb  
> entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
>  - Remove E.HV.LRAT from vcpus
> 
>  arch/powerpc/kvm/e500_mmu.c |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
>  	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
> 
>  	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> +		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
> +
>  		if (has_feature(vcpu, VCPU_FTR_E_PT))
>  			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
>  		else
>  			vcpu->arch.eptcfg = 0;
> 
> +		/* Guest mmu emulation currently doesn't handle E.PT */
> +		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
> +		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;

You're clearing these bits *after* calling has_feature() -- doesn't  
has_feature() depend on those bits being cleared to not advertise E_PT  
support?

-Scott

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

* RE: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-26 22:42     ` Scott Wood
@ 2013-04-04 13:26       ` Caraman Mihai Claudiu-B02008
  -1 siblings, 0 replies; 43+ messages in thread
From: Caraman Mihai Claudiu-B02008 @ 2013-04-04 13:26 UTC (permalink / raw)
  To: Wood Scott-B07421; +Cc: kvm-ppc, kvm, agraf

> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Wednesday, March 27, 2013 12:43 AM
> To: Caraman Mihai Claudiu-B02008
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de
> Subject: Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via
> ONE_REG
> 
> On 03/26/2013 05:05:06 PM, Mihai Caraman wrote:
> > +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> > +			       union kvmppc_one_reg *val)
> > +{
> > +	int r = 0;
> > +	long int i;
> > +
> > +	switch (id) {
> > +	case KVM_REG_PPC_MAS0:
> > +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS1:
> > +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS2:
> > +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS7_3:
> > +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS4:
> > +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS6:
> > +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> > +		break;
> > +	/* Only allow MMU registers to be set to the config supported
> > by KVM */
> > +	case KVM_REG_PPC_MMUCFG: {
> > +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> > +			r = -EINVAL;
> > +		break;
> > +	}
> > +	case KVM_REG_PPC_TLB0CFG:
> > +	case KVM_REG_PPC_TLB1CFG:
> > +	case KVM_REG_PPC_TLB2CFG:
> > +	case KVM_REG_PPC_TLB3CFG: {
> > +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using
> > SW_TLB */
> > +		i = id - KVM_REG_PPC_TLB0CFG;
> > +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> > +			r = -EINVAL;
> > +		break;
> > +	}
> 
> Am I the only one that finds the set_reg_val/get_reg_val naming
> confusing?  At first glance it looks like it sets TLBnCFG and then
> later tests whether it should have. :-P
> 
> Functions should be named for what they do, not for what context you
> use them in.

I also found the existing code difficult to read. If we stick to reg and
val varible names what about val_to_reg/reg_to_val.
 
-Mike

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

* RE: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-04-04 13:26       ` Caraman Mihai Claudiu-B02008
  0 siblings, 0 replies; 43+ messages in thread
From: Caraman Mihai Claudiu-B02008 @ 2013-04-04 13:26 UTC (permalink / raw)
  To: Wood Scott-B07421; +Cc: kvm-ppc, kvm, agraf

> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Wednesday, March 27, 2013 12:43 AM
> To: Caraman Mihai Claudiu-B02008
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de
> Subject: Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via
> ONE_REG
> 
> On 03/26/2013 05:05:06 PM, Mihai Caraman wrote:
> > +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> > +			       union kvmppc_one_reg *val)
> > +{
> > +	int r = 0;
> > +	long int i;
> > +
> > +	switch (id) {
> > +	case KVM_REG_PPC_MAS0:
> > +		vcpu->arch.shared->mas0 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS1:
> > +		vcpu->arch.shared->mas1 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS2:
> > +		vcpu->arch.shared->mas2 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS7_3:
> > +		vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS4:
> > +		vcpu->arch.shared->mas4 = set_reg_val(id, *val);
> > +		break;
> > +	case KVM_REG_PPC_MAS6:
> > +		vcpu->arch.shared->mas6 = set_reg_val(id, *val);
> > +		break;
> > +	/* Only allow MMU registers to be set to the config supported
> > by KVM */
> > +	case KVM_REG_PPC_MMUCFG: {
> > +		if (set_reg_val(id, *val) != vcpu->arch.mmucfg)
> > +			r = -EINVAL;
> > +		break;
> > +	}
> > +	case KVM_REG_PPC_TLB0CFG:
> > +	case KVM_REG_PPC_TLB1CFG:
> > +	case KVM_REG_PPC_TLB2CFG:
> > +	case KVM_REG_PPC_TLB3CFG: {
> > +		/* MMU geometry (N_ENTRY/ASSOC) can be set only using
> > SW_TLB */
> > +		i = id - KVM_REG_PPC_TLB0CFG;
> > +		if (set_reg_val(id, *val) != vcpu->arch.tlbcfg[i])
> > +			r = -EINVAL;
> > +		break;
> > +	}
> 
> Am I the only one that finds the set_reg_val/get_reg_val naming
> confusing?  At first glance it looks like it sets TLBnCFG and then
> later tests whether it should have. :-P
> 
> Functions should be named for what they do, not for what context you
> use them in.

I also found the existing code difficult to read. If we stick to reg and
val varible names what about val_to_reg/reg_to_val.
 
-Mike


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

end of thread, other threads:[~2013-04-04 13:26 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core Mihai Caraman
2013-03-26 22:05 ` Mihai Caraman
2013-03-26 22:05 ` Mihai Caraman
2013-03-26 22:05 ` [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:42   ` Scott Wood
2013-03-26 22:42     ` Scott Wood
2013-04-04 13:26     ` Caraman Mihai Claudiu-B02008
2013-04-04 13:26       ` Caraman Mihai Claudiu-B02008
2013-03-27 15:58   ` Alexander Graf
2013-03-27 15:58     ` Alexander Graf
2013-03-27 15:58     ` Alexander Graf
2013-03-26 22:05 ` [PATCH 2/7 v2] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05 ` [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:48   ` Scott Wood
2013-03-26 22:48     ` Scott Wood
2013-03-26 22:48     ` Scott Wood
2013-03-26 22:05 ` [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-27 17:21   ` Alexander Graf
2013-03-27 17:21     ` Alexander Graf
2013-03-27 17:21     ` Alexander Graf
2013-03-26 22:05 ` [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-27 17:23   ` Alexander Graf
2013-03-27 17:23     ` Alexander Graf
2013-03-27 17:23     ` Alexander Graf
2013-03-27 17:50   ` Scott Wood
2013-03-27 17:50     ` Scott Wood
2013-03-27 17:50     ` Scott Wood
2013-03-26 22:05 ` [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05 ` [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman
2013-03-26 22:05   ` Mihai Caraman

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.