KVM: PPC: e500: Expose MMU registers via ONE_REG
MMU registers were exposed to user-space using sregs interface. Add them to ONE_REG interface using kvmppc_get_one_reg/kvmppc_set_one_reg delegation mechanism. Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
35b299e279
commit
a85d2aa23e
|
@ -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:
|
||||
|
|
|
@ -449,4 +449,21 @@ struct kvm_get_htab_header {
|
|||
/* Debugging: Special instruction for software breakpoint */
|
||||
#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
|
||||
|
||||
/* MMU registers */
|
||||
#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
|
||||
#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d)
|
||||
#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
|
||||
#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f)
|
||||
#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
|
||||
#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
|
||||
#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
|
||||
/*
|
||||
* 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 | 0x93)
|
||||
#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
|
||||
#define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
|
||||
#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
|
||||
|
||||
#endif /* __LINUX_KVM_POWERPC_H */
|
||||
|
|
|
@ -428,13 +428,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
|||
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||
union kvmppc_one_reg *val)
|
||||
{
|
||||
return -EINVAL;
|
||||
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)
|
||||
{
|
||||
return -EINVAL;
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -596,6 +596,100 @@ 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);
|
||||
break;
|
||||
case KVM_REG_PPC_MAS1:
|
||||
*val = get_reg_val(id, vcpu->arch.shared->mas1);
|
||||
break;
|
||||
case KVM_REG_PPC_MAS2:
|
||||
*val = get_reg_val(id, vcpu->arch.shared->mas2);
|
||||
break;
|
||||
case KVM_REG_PPC_MAS7_3:
|
||||
*val = get_reg_val(id, vcpu->arch.shared->mas7_3);
|
||||
break;
|
||||
case KVM_REG_PPC_MAS4:
|
||||
*val = get_reg_val(id, vcpu->arch.shared->mas4);
|
||||
break;
|
||||
case KVM_REG_PPC_MAS6:
|
||||
*val = get_reg_val(id, vcpu->arch.shared->mas6);
|
||||
break;
|
||||
case KVM_REG_PPC_MMUCFG:
|
||||
*val = get_reg_val(id, vcpu->arch.mmucfg);
|
||||
break;
|
||||
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]);
|
||||
break;
|
||||
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: {
|
||||
u32 reg = set_reg_val(id, *val);
|
||||
if (reg != 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 */
|
||||
u32 reg = set_reg_val(id, *val);
|
||||
i = id - KVM_REG_PPC_TLB0CFG;
|
||||
if (reg != 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)
|
||||
{
|
||||
|
|
|
@ -258,13 +258,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
|||
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||
union kvmppc_one_reg *val)
|
||||
{
|
||||
return -EINVAL;
|
||||
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)
|
||||
{
|
||||
return -EINVAL;
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue