* [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core @ 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 ` (6 more replies) 0 siblings, 7 replies; 13+ 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] 13+ messages in thread
* [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG 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-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 ` (5 subsequent siblings) 6 siblings, 1 reply; 13+ 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] 13+ messages in thread
* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG 2013-03-26 22:05 ` [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG Mihai Caraman @ 2013-03-27 15:58 ` Alexander Graf 0 siblings, 0 replies; 13+ 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] 13+ messages in thread
* [PATCH 2/7 v2] KVM: PPC: e500: Move vcpu's MMU configuration to dedicated functions 2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core 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 ` [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers Mihai Caraman ` (4 subsequent siblings) 6 siblings, 0 replies; 13+ 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, ¶ms); 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] 13+ messages in thread
* [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers 2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core 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 ` [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:48 ` Scott Wood 2013-03-26 22:05 ` [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register Mihai Caraman ` (3 subsequent siblings) 6 siblings, 1 reply; 13+ 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] 13+ messages in thread
* Re: [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers 2013-03-26 22:05 ` [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers Mihai Caraman @ 2013-03-26 22:48 ` Scott Wood 0 siblings, 0 replies; 13+ 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] 13+ messages in thread
* [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register 2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core Mihai Caraman ` (2 preceding siblings ...) 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-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 ` (2 subsequent siblings) 6 siblings, 1 reply; 13+ 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] 13+ messages in thread
* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register 2013-03-26 22:05 ` [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register Mihai Caraman @ 2013-03-27 17:21 ` Alexander Graf 0 siblings, 0 replies; 13+ 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] 13+ 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 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core Mihai Caraman ` (3 preceding siblings ...) 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-27 17:23 ` Alexander Graf 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 ` [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description Mihai Caraman 6 siblings, 2 replies; 13+ 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] 13+ 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 ` [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs Mihai Caraman @ 2013-03-27 17:23 ` Alexander Graf 2013-03-27 17:50 ` Scott Wood 1 sibling, 0 replies; 13+ 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] 13+ 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 ` [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs Mihai Caraman 2013-03-27 17:23 ` Alexander Graf @ 2013-03-27 17:50 ` Scott Wood 1 sibling, 0 replies; 13+ 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] 13+ messages in thread
* [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores 2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core Mihai Caraman ` (4 preceding siblings ...) 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 ` [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description Mihai Caraman 6 siblings, 0 replies; 13+ 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] 13+ messages in thread
* [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description 2013-03-26 22:05 [PATCH 0/7 v2] KVM: PPC: e500: Enable FSL e6500 core Mihai Caraman ` (5 preceding siblings ...) 2013-03-26 22:05 ` [PATCH 6/7 v2] KVM: PPC: e500mc: Enable e6500 cores Mihai Caraman @ 2013-03-26 22:05 ` Mihai Caraman 6 siblings, 0 replies; 13+ 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] 13+ messages in thread
end of thread, other threads:[~2013-03-27 17:51 UTC | newest] Thread overview: 13+ 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 ` [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG Mihai Caraman 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 ` [PATCH 3/7 v2] KVM: PPC: e500: Add support for TLBnPS registers Mihai Caraman 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-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-27 17:23 ` Alexander Graf 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 ` [PATCH 7/7 v2] KVM: PPC: e500: Add e6500 core to Kconfig description Mihai Caraman
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).