* [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: kvm, linuxppc-dev, Mihai Caraman
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: kvm-ppc, Mihai Caraman, linuxppc-dev, kvm
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 = 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;
> + }
Do we really want to allow arbitrary MMUCFG changes? It won't
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 = 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;
> + }
Likewise -- just because QEMU sets a bit here doesn't mean KVM can
support it.
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.
-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, kvm-ppc, linuxppc-dev, kvm
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 = 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;
>> + }
>
> 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.
>
>> + 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;
>> + }
>
> Likewise -- just because QEMU sets a bit here doesn't mean KVM can support it.
>
> 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: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
kvm@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
>
>
> 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 = 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;
> >> + }
> >
> > 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) != vcpu->arch.mmucfg)
r = -EINVAL;
break;
}
>
> 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, kvm-ppc@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org
On 21.03.2013, at 12:02, Caraman Mihai Claudiu-B02008 wrote:
>
>
>> -----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 = 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;
>>>> + }
>>>
>>> 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) != vcpu->arch.mmucfg)
> r = -EINVAL;
> break;
> }
Yes :).
>
>>
>> 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.
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, kvm-ppc@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, kvm@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
>
>
> On 21.03.2013, at 12:02, Caraman Mihai Claudiu-B02008 wrote:
>
> >
> >
> >> -----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 = 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;
> >>>> + }
> >>>
> >>> 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) != vcpu->arch.mmucfg)
> > r = -EINVAL;
> > break;
> > }
>
> Yes :).
>
> >
> >>
> >> 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.
>
> 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).