KVM: PPC: e500: Add support for EPTCFG register

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

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Mihai Caraman 2013-04-11 00:03:11 +00:00 committed by Alexander Graf
parent 307d9008ed
commit 9a6061d7fd
5 changed files with 24 additions and 0 deletions

View file

@ -1807,6 +1807,7 @@ registers, find a list below:
PPC | KVM_REG_PPC_TLB1PS | 32 PPC | KVM_REG_PPC_TLB1PS | 32
PPC | KVM_REG_PPC_TLB2PS | 32 PPC | KVM_REG_PPC_TLB2PS | 32
PPC | KVM_REG_PPC_TLB3PS | 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 ARM registers are mapped using the lower 32 bits. The upper 16 of that
is the register group type, or coprocessor number: is the register group type, or coprocessor number:

View file

@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
u32 tlbcfg[4]; u32 tlbcfg[4];
u32 tlbps[4]; u32 tlbps[4];
u32 mmucfg; u32 mmucfg;
u32 eptcfg;
u32 epr; u32 epr;
u32 crit_save; u32 crit_save;
struct kvmppc_booke_debug_reg dbg_reg; struct kvmppc_booke_debug_reg dbg_reg;

View file

@ -469,5 +469,6 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98) #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
#define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99) #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
#define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b)
#endif /* __LINUX_KVM_POWERPC_H */ #endif /* __LINUX_KVM_POWERPC_H */

View file

@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
case SPRN_MMUCFG: case SPRN_MMUCFG:
*spr_val = vcpu->arch.mmucfg; *spr_val = vcpu->arch.mmucfg;
break; 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 */ /* extra exceptions */
case SPRN_IVOR32: case SPRN_IVOR32:

View file

@ -624,6 +624,9 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_MMUCFG: case KVM_REG_PPC_MMUCFG:
*val = get_reg_val(id, vcpu->arch.mmucfg); *val = get_reg_val(id, vcpu->arch.mmucfg);
break; break;
case KVM_REG_PPC_EPTCFG:
*val = get_reg_val(id, vcpu->arch.eptcfg);
break;
case KVM_REG_PPC_TLB0CFG: case KVM_REG_PPC_TLB0CFG:
case KVM_REG_PPC_TLB1CFG: case KVM_REG_PPC_TLB1CFG:
case KVM_REG_PPC_TLB2CFG: case KVM_REG_PPC_TLB2CFG:
@ -678,6 +681,12 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
r = -EINVAL; r = -EINVAL;
break; break;
} }
case KVM_REG_PPC_EPTCFG: {
u32 reg = set_reg_val(id, *val);
if (reg != vcpu->arch.eptcfg)
r = -EINVAL;
break;
}
case KVM_REG_PPC_TLB0CFG: case KVM_REG_PPC_TLB0CFG:
case KVM_REG_PPC_TLB1CFG: case KVM_REG_PPC_TLB1CFG:
case KVM_REG_PPC_TLB2CFG: case KVM_REG_PPC_TLB2CFG:
@ -875,6 +884,9 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
if (has_feature(vcpu, VCPU_FTR_MMU_V2)) { if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS); vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS); vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
/* Guest mmu emulation currently doesn't handle E.PT */
vcpu->arch.eptcfg = 0;
} }
return 0; return 0;