forked from luck/tmp_suning_uos_patched
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_TSR | 32
|
||||||
PPC | KVM_REG_PPC_OR_TSR | 32
|
PPC | KVM_REG_PPC_OR_TSR | 32
|
||||||
PPC | KVM_REG_PPC_CLEAR_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
|
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:
|
||||||
|
|
|
@ -449,4 +449,21 @@ struct kvm_get_htab_header {
|
||||||
/* Debugging: Special instruction for software breakpoint */
|
/* Debugging: Special instruction for software breakpoint */
|
||||||
#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
|
#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 */
|
#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,
|
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
union kvmppc_one_reg *val)
|
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,
|
int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
union kvmppc_one_reg *val)
|
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)
|
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);
|
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_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
|
#ifdef CONFIG_KVM_E500V2
|
||||||
unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
|
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;
|
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,
|
int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
|
||||||
struct kvm_config_tlb *cfg)
|
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,
|
int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
union kvmppc_one_reg *val)
|
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,
|
int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||||
union kvmppc_one_reg *val)
|
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)
|
struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user