linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
@ 2013-03-19 17:17 Mihai Caraman
  2013-03-19 17:26 ` Scott Wood
  0 siblings, 1 reply; 6+ messages in thread
From: Mihai Caraman @ 2013-03-19 17:17 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.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
 Documentation/virtual/kvm/api.txt   |   13 +++++
 arch/powerpc/include/uapi/asm/kvm.h |   14 ++++++
 arch/powerpc/kvm/44x.c              |   12 +++++
 arch/powerpc/kvm/booke.c            |   67 +++++++++++++++++---------
 arch/powerpc/kvm/e500.c             |   14 ++++++
 arch/powerpc/kvm/e500.h             |    4 ++
 arch/powerpc/kvm/e500_mmu.c         |   89 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/e500mc.c           |   15 ++++++
 8 files changed, 204 insertions(+), 24 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index c2534c3..9aee4dd 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1763,6 +1763,19 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_EPCR	| 32
   PPC   | KVM_REG_PPC_EPR	| 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
+
 4.69 KVM_GET_ONE_REG
 
 Capability: KVM_CAP_ONE_REG
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 16064d0..70dfeef 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -417,4 +417,18 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
 #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
 
+/* MMU registers */
+#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
+#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
+#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x89)
+#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8a)
+#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
+#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
+#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d)
+/* TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using SW_TLB ioctl */
+#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8e)
+#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
+#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
+#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
+
 #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 020923e..1b25923d 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1409,81 +1409,100 @@ 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
 	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
 	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..75875a9 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_500_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_500_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 41cefd4..fe17f40 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -139,6 +139,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_500_tlb(struct kvm_vcpu *vcpu, u64 id,
+				union kvmppc_one_reg *val);
+int kvmppc_set_one_reg_500_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 66b6e31..b77b855 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return 0;
 }
 
+int kvmppc_get_one_reg_500_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_500_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;
+	case KVM_REG_PPC_MMUCFG: {
+		u32 mmucfg = set_reg_val(id, *val);
+		vcpu->arch.mmucfg = mmucfg & ~MMUCFG_LPIDSIZE;
+		break;
+	}
+	case KVM_REG_PPC_TLB0CFG:
+	case KVM_REG_PPC_TLB1CFG:
+	case KVM_REG_PPC_TLB2CFG:
+	case KVM_REG_PPC_TLB3CFG: {
+		u32 tlbncfg = set_reg_val(id, *val);				
+		u32 geometry_mask = TLBnCFG_N_ENTRY | TLBnCFG_ASSOC;
+		i = id - KVM_REG_PPC_TLB0CFG;
+
+		/* MMU geometry (way/size) can be set only using SW_TLB */
+		if ((vcpu->arch.tlbcfg[i] & geometry_mask) !=
+		    (tlbncfg & geometry_mask))
+			r = -EINVAL;
+
+		vcpu->arch.tlbcfg[i] = set_reg_val(id, *val);
+		break;
+	}
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
 static int vcpu_mmu_geometry_update(struct kvm_vcpu *vcpu,
 		struct kvm_book3e_206_tlb_params *params)
 {
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..c255259 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_500_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_500_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;
@@ -337,6 +351,7 @@ static int __init kvmppc_e500mc_init(void)
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
 }
 
+
 static void __exit kvmppc_e500mc_exit(void)
 {
 	kvmppc_booke_exit();
-- 
1.7.4.1

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

* Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-19 17:17 [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG Mihai Caraman
@ 2013-03-19 17:26 ` Scott Wood
  2013-03-21 10:06   ` Alexander Graf
  0 siblings, 1 reply; 6+ messages in thread
From: Scott Wood @ 2013-03-19 17:26 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc

On 03/19/2013 12:17:11 PM, Mihai Caraman wrote:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 66b6e31..b77b855 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu =20
> *vcpu, struct kvm_sregs *sregs)
>  	return 0;
>  }
>=20
> +int kvmppc_get_one_reg_500_tlb(struct kvm_vcpu *vcpu, u64 id,
> +				union kvmppc_one_reg *val)

s/500/e500/

> +int kvmppc_set_one_reg_500_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;
> +	case KVM_REG_PPC_MMUCFG: {
> +		u32 mmucfg =3D set_reg_val(id, *val);
> +		vcpu->arch.mmucfg =3D mmucfg & ~MMUCFG_LPIDSIZE;
> +		break;
> +	}

Do we really want to allow arbitrary MMUCFG changes?  It won't =20
magically make us able to support larger RAs, PIDs, different MAVN, etc.

> +	case KVM_REG_PPC_TLB0CFG:
> +	case KVM_REG_PPC_TLB1CFG:
> +	case KVM_REG_PPC_TLB2CFG:
> +	case KVM_REG_PPC_TLB3CFG: {
> +		u32 tlbncfg =3D set_reg_val(id, =20
> *val);			=09
> +		u32 geometry_mask =3D TLBnCFG_N_ENTRY | TLBnCFG_ASSOC;
> +		i =3D id - KVM_REG_PPC_TLB0CFG;
> +
> +		/* MMU geometry (way/size) can be set only using SW_TLB =20
> */
> +		if ((vcpu->arch.tlbcfg[i] & geometry_mask) !=3D
> +		    (tlbncfg & geometry_mask))
> +			r =3D -EINVAL;
> +
> +		vcpu->arch.tlbcfg[i] =3D set_reg_val(id, *val);
> +		break;
> +	}

Likewise -- just because QEMU sets a bit here doesn't mean KVM can =20
support it.

I thought the initial plan for setting these config registers was to =20
accept it if it exactly matches what KVM already has, and give an error =20
otherwise -- thus allowing for the possibliity of accepting certain =20
specific updates in the future.

-Scott=

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

* Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-19 17:26 ` Scott Wood
@ 2013-03-21 10:06   ` Alexander Graf
  2013-03-21 11:02     ` Caraman Mihai Claudiu-B02008
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander Graf @ 2013-03-21 10:06 UTC (permalink / raw)
  To: Scott Wood; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc


On 19.03.2013, at 18:26, Scott Wood wrote:

> On 03/19/2013 12:17:11 PM, Mihai Caraman wrote:
>> diff --git a/arch/powerpc/kvm/e500_mmu.c =
b/arch/powerpc/kvm/e500_mmu.c
>> index 66b6e31..b77b855 100644
>> --- a/arch/powerpc/kvm/e500_mmu.c
>> +++ b/arch/powerpc/kvm/e500_mmu.c
>> @@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu =
*vcpu, struct kvm_sregs *sregs)
>> 	return 0;
>> }
>> +int kvmppc_get_one_reg_500_tlb(struct kvm_vcpu *vcpu, u64 id,
>> +				union kvmppc_one_reg *val)
>=20
> s/500/e500/
>=20
>> +int kvmppc_set_one_reg_500_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;
>> +	case KVM_REG_PPC_MMUCFG: {
>> +		u32 mmucfg =3D set_reg_val(id, *val);
>> +		vcpu->arch.mmucfg =3D mmucfg & ~MMUCFG_LPIDSIZE;
>> +		break;
>> +	}
>=20
> Do we really want to allow arbitrary MMUCFG changes?  It won't =
magically make us able to support larger RAs, PIDs, different MAVN, etc.

Only if we update the actual shadow mmu configuration as well.

>=20
>> +	case KVM_REG_PPC_TLB0CFG:
>> +	case KVM_REG_PPC_TLB1CFG:
>> +	case KVM_REG_PPC_TLB2CFG:
>> +	case KVM_REG_PPC_TLB3CFG: {
>> +		u32 tlbncfg =3D set_reg_val(id, *val);			=09=

>> +		u32 geometry_mask =3D TLBnCFG_N_ENTRY | TLBnCFG_ASSOC;
>> +		i =3D id - KVM_REG_PPC_TLB0CFG;
>> +
>> +		/* MMU geometry (way/size) can be set only using SW_TLB =
*/
>> +		if ((vcpu->arch.tlbcfg[i] & geometry_mask) !=3D
>> +		    (tlbncfg & geometry_mask))
>> +			r =3D -EINVAL;
>> +
>> +		vcpu->arch.tlbcfg[i] =3D set_reg_val(id, *val);
>> +		break;
>> +	}
>=20
> Likewise -- just because QEMU sets a bit here doesn't mean KVM can =
support it.
>=20
> I thought the initial plan for setting these config registers was to =
accept it if it exactly matches what KVM already has, and give an error =
otherwise -- thus allowing for the possibliity of accepting certain =
specific updates in the future.

Yes, that was the idea :).


Alex

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

* RE: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-21 10:06   ` Alexander Graf
@ 2013-03-21 11:02     ` Caraman Mihai Claudiu-B02008
  2013-03-21 11:06       ` Alexander Graf
  0 siblings, 1 reply; 6+ messages in thread
From: Caraman Mihai Claudiu-B02008 @ 2013-03-21 11:02 UTC (permalink / raw)
  To: Alexander Graf, Wood Scott-B07421
  Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
	kvm-ppc@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Thursday, March 21, 2013 12:07 PM
> To: Wood Scott-B07421
> Cc: Caraman Mihai Claudiu-B02008; kvm-ppc@vger.kernel.org; linuxppc-
> dev@lists.ozlabs.org; kvm@vger.kernel.org
> Subject: Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
>=20
>=20
> On 19.03.2013, at 18:26, Scott Wood wrote:
>=20
> > On 03/19/2013 12:17:11 PM, Mihai Caraman wrote:
> >> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> >> index 66b6e31..b77b855 100644
> >> --- a/arch/powerpc/kvm/e500_mmu.c
> >> +++ b/arch/powerpc/kvm/e500_mmu.c
> >> @@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu
> *vcpu, struct kvm_sregs *sregs)
> >> 	return 0;
> >> }
> >> +int kvmppc_get_one_reg_500_tlb(struct kvm_vcpu *vcpu, u64 id,
> >> +				union kvmppc_one_reg *val)
> >
> > s/500/e500/
> >
> >> +int kvmppc_set_one_reg_500_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;
> >> +	case KVM_REG_PPC_MMUCFG: {
> >> +		u32 mmucfg =3D set_reg_val(id, *val);
> >> +		vcpu->arch.mmucfg =3D mmucfg & ~MMUCFG_LPIDSIZE;
> >> +		break;
> >> +	}
> >
> > Do we really want to allow arbitrary MMUCFG changes?  It won't
> magically make us able to support larger RAs, PIDs, different MAVN, etc.

Not magically, some changes e.g TLBnCFG_IND or TLBnPS require just a kvm
check other changes e.g. TLBnCFG_MAVN require additional support and we
might not implement all of them. Until then this code should do the job:

	/* MMU registers can be set only to the configuration supported by KVM */
	case KVM_REG_PPC_MMUCFG: {
		if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
			r =3D -EINVAL;
		break;
	}

>=20
> Only if we update the actual shadow mmu configuration as well.

These registers (MMUCFG, EPTCFG, TLBnCFG, TLBnPS) are read-only (and shared
between e6500 threads), we can only emulate them.

-Mike

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

* Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-21 11:02     ` Caraman Mihai Claudiu-B02008
@ 2013-03-21 11:06       ` Alexander Graf
  2013-03-21 11:42         ` Caraman Mihai Claudiu-B02008
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander Graf @ 2013-03-21 11:06 UTC (permalink / raw)
  To: Caraman Mihai Claudiu-B02008
  Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org,
	kvm@vger.kernel.org, kvm-ppc@vger.kernel.org


On 21.03.2013, at 12:02, Caraman Mihai Claudiu-B02008 wrote:

>=20
>=20
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Thursday, March 21, 2013 12:07 PM
>> To: Wood Scott-B07421
>> Cc: Caraman Mihai Claudiu-B02008; kvm-ppc@vger.kernel.org; linuxppc-
>> dev@lists.ozlabs.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
>>=20
>>=20
>> On 19.03.2013, at 18:26, Scott Wood wrote:
>>=20
>>> On 03/19/2013 12:17:11 PM, Mihai Caraman wrote:
>>>> diff --git a/arch/powerpc/kvm/e500_mmu.c =
b/arch/powerpc/kvm/e500_mmu.c
>>>> index 66b6e31..b77b855 100644
>>>> --- a/arch/powerpc/kvm/e500_mmu.c
>>>> +++ b/arch/powerpc/kvm/e500_mmu.c
>>>> @@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu
>> *vcpu, struct kvm_sregs *sregs)
>>>> 	return 0;
>>>> }
>>>> +int kvmppc_get_one_reg_500_tlb(struct kvm_vcpu *vcpu, u64 id,
>>>> +				union kvmppc_one_reg *val)
>>>=20
>>> s/500/e500/
>>>=20
>>>> +int kvmppc_set_one_reg_500_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;
>>>> +	case KVM_REG_PPC_MMUCFG: {
>>>> +		u32 mmucfg =3D set_reg_val(id, *val);
>>>> +		vcpu->arch.mmucfg =3D mmucfg & ~MMUCFG_LPIDSIZE;
>>>> +		break;
>>>> +	}
>>>=20
>>> Do we really want to allow arbitrary MMUCFG changes?  It won't
>> magically make us able to support larger RAs, PIDs, different MAVN, =
etc.
>=20
> Not magically, some changes e.g TLBnCFG_IND or TLBnPS require just a =
kvm
> check other changes e.g. TLBnCFG_MAVN require additional support and =
we
> might not implement all of them. Until then this code should do the =
job:
>=20
> 	/* MMU registers can be set only to the configuration supported =
by KVM */
> 	case KVM_REG_PPC_MMUCFG: {
> 		if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
> 			r =3D -EINVAL;
> 		break;
> 	}

Yes :).

>=20
>>=20
>> Only if we update the actual shadow mmu configuration as well.
>=20
> These registers (MMUCFG, EPTCFG, TLBnCFG, TLBnPS) are read-only (and =
shared
> between e6500 threads), we can only emulate them.

We need to change the behavior of the shadow mmu as well. It's not about =
the registers, but the actually exposed TLBs. If you configure 4 TLBs, =
and you announce to the guest that you can do 4 TLBs, you better emulate =
4 TLBs :).


Alex

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

* RE: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
  2013-03-21 11:06       ` Alexander Graf
@ 2013-03-21 11:42         ` Caraman Mihai Claudiu-B02008
  0 siblings, 0 replies; 6+ messages in thread
From: Caraman Mihai Claudiu-B02008 @ 2013-03-21 11:42 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org,
	kvm@vger.kernel.org, kvm-ppc@vger.kernel.org

> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Thursday, March 21, 2013 1:07 PM
> To: Caraman Mihai Claudiu-B02008
> Cc: Wood Scott-B07421; kvm-ppc@vger.kernel.org; linuxppc-
> dev@lists.ozlabs.org; kvm@vger.kernel.org
> Subject: Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
>=20
>=20
> On 21.03.2013, at 12:02, Caraman Mihai Claudiu-B02008 wrote:
>=20
> >
> >
> >> -----Original Message-----
> >> From: Alexander Graf [mailto:agraf@suse.de]
> >> Sent: Thursday, March 21, 2013 12:07 PM
> >> To: Wood Scott-B07421
> >> Cc: Caraman Mihai Claudiu-B02008; kvm-ppc@vger.kernel.org; linuxppc-
> >> dev@lists.ozlabs.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG
> >>
> >>
> >> On 19.03.2013, at 18:26, Scott Wood wrote:
> >>
> >>> On 03/19/2013 12:17:11 PM, Mihai Caraman wrote:
> >>>> diff --git a/arch/powerpc/kvm/e500_mmu.c
> b/arch/powerpc/kvm/e500_mmu.c
> >>>> index 66b6e31..b77b855 100644
> >>>> --- a/arch/powerpc/kvm/e500_mmu.c
> >>>> +++ b/arch/powerpc/kvm/e500_mmu.c
> >>>> @@ -596,6 +596,95 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu
> >> *vcpu, struct kvm_sregs *sregs)
> >>>> 	return 0;
> >>>> }
> >>>> +int kvmppc_get_one_reg_500_tlb(struct kvm_vcpu *vcpu, u64 id,
> >>>> +				union kvmppc_one_reg *val)
> >>>
> >>> s/500/e500/
> >>>
> >>>> +int kvmppc_set_one_reg_500_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;
> >>>> +	case KVM_REG_PPC_MMUCFG: {
> >>>> +		u32 mmucfg =3D set_reg_val(id, *val);
> >>>> +		vcpu->arch.mmucfg =3D mmucfg & ~MMUCFG_LPIDSIZE;
> >>>> +		break;
> >>>> +	}
> >>>
> >>> Do we really want to allow arbitrary MMUCFG changes?  It won't
> >> magically make us able to support larger RAs, PIDs, different MAVN,
> etc.
> >
> > Not magically, some changes e.g TLBnCFG_IND or TLBnPS require just a
> kvm
> > check other changes e.g. TLBnCFG_MAVN require additional support and we
> > might not implement all of them. Until then this code should do the
> job:
> >
> > 	/* MMU registers can be set only to the configuration supported by
> KVM */
> > 	case KVM_REG_PPC_MMUCFG: {
> > 		if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
> > 			r =3D -EINVAL;
> > 		break;
> > 	}
>=20
> Yes :).
>=20
> >
> >>
> >> Only if we update the actual shadow mmu configuration as well.
> >
> > These registers (MMUCFG, EPTCFG, TLBnCFG, TLBnPS) are read-only (and
> shared
> > between e6500 threads), we can only emulate them.
>=20
> We need to change the behavior of the shadow mmu as well. It's not about
> the registers, but the actually exposed TLBs. If you configure 4 TLBs,
> and you announce to the guest that you can do 4 TLBs, you better emulate
> 4 TLBs :).

Right, like the rest of configs I was talking above:)

-Mike

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

end of thread, other threads:[~2013-03-21 11:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-19 17:17 [PATCH] KVM: PPC: e500: Expose MMU registers via ONE_REG Mihai Caraman
2013-03-19 17:26 ` Scott Wood
2013-03-21 10:06   ` Alexander Graf
2013-03-21 11:02     ` Caraman Mihai Claudiu-B02008
2013-03-21 11:06       ` Alexander Graf
2013-03-21 11:42         ` Caraman Mihai Claudiu-B02008

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).