diff options
author | Mihai Caraman <mihai.caraman@freescale.com> | 2013-04-10 20:03:11 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-04-26 14:27:08 -0400 |
commit | 9a6061d7fdedbf025549adf5c9d920d90bbf4a69 (patch) | |
tree | 65057dad1b9ed9255175c19b8fe52cad37d91500 | |
parent | 307d9008ed4f28920e0e78719e10d0f407341e00 (diff) |
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>
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/kvm.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_mmu.c | 12 |
5 files changed, 24 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index f045377ae5a0..a1f2200e43d0 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1807,6 +1807,7 @@ registers, find a list below: | |||
1807 | PPC | KVM_REG_PPC_TLB1PS | 32 | 1807 | PPC | KVM_REG_PPC_TLB1PS | 32 |
1808 | PPC | KVM_REG_PPC_TLB2PS | 32 | 1808 | PPC | KVM_REG_PPC_TLB2PS | 32 |
1809 | PPC | KVM_REG_PPC_TLB3PS | 32 | 1809 | PPC | KVM_REG_PPC_TLB3PS | 32 |
1810 | PPC | KVM_REG_PPC_EPTCFG | 32 | ||
1810 | 1811 | ||
1811 | ARM registers are mapped using the lower 32 bits. The upper 16 of that | 1812 | ARM registers are mapped using the lower 32 bits. The upper 16 of that |
1812 | is the register group type, or coprocessor number: | 1813 | 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 3b6cee3e33a8..8a48e686a755 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 { | |||
504 | u32 tlbcfg[4]; | 504 | u32 tlbcfg[4]; |
505 | u32 tlbps[4]; | 505 | u32 tlbps[4]; |
506 | u32 mmucfg; | 506 | u32 mmucfg; |
507 | u32 eptcfg; | ||
507 | u32 epr; | 508 | u32 epr; |
508 | u32 crit_save; | 509 | u32 crit_save; |
509 | struct kvmppc_booke_debug_reg dbg_reg; | 510 | 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 4dd36c399842..41d59d8bdfe8 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h | |||
@@ -469,5 +469,6 @@ struct kvm_get_htab_header { | |||
469 | #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98) | 469 | #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98) |
470 | #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99) | 470 | #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99) |
471 | #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) | 471 | #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) |
472 | #define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b) | ||
472 | 473 | ||
473 | #endif /* __LINUX_KVM_POWERPC_H */ | 474 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 12b8de2f91ed..b10a01243abd 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) | |||
317 | case SPRN_MMUCFG: | 317 | case SPRN_MMUCFG: |
318 | *spr_val = vcpu->arch.mmucfg; | 318 | *spr_val = vcpu->arch.mmucfg; |
319 | break; | 319 | break; |
320 | case SPRN_EPTCFG: | ||
321 | if (!has_feature(vcpu, VCPU_FTR_MMU_V2)) | ||
322 | return EMULATE_FAIL; | ||
323 | /* | ||
324 | * Legacy Linux guests access EPTCFG register even if the E.PT | ||
325 | * category is disabled in the VM. Give them a chance to live. | ||
326 | */ | ||
327 | *spr_val = vcpu->arch.eptcfg; | ||
328 | break; | ||
320 | 329 | ||
321 | /* extra exceptions */ | 330 | /* extra exceptions */ |
322 | case SPRN_IVOR32: | 331 | case SPRN_IVOR32: |
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index a863dc1791eb..1c1c5cb78495 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c | |||
@@ -624,6 +624,9 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | |||
624 | case KVM_REG_PPC_MMUCFG: | 624 | case KVM_REG_PPC_MMUCFG: |
625 | *val = get_reg_val(id, vcpu->arch.mmucfg); | 625 | *val = get_reg_val(id, vcpu->arch.mmucfg); |
626 | break; | 626 | break; |
627 | case KVM_REG_PPC_EPTCFG: | ||
628 | *val = get_reg_val(id, vcpu->arch.eptcfg); | ||
629 | break; | ||
627 | case KVM_REG_PPC_TLB0CFG: | 630 | case KVM_REG_PPC_TLB0CFG: |
628 | case KVM_REG_PPC_TLB1CFG: | 631 | case KVM_REG_PPC_TLB1CFG: |
629 | case KVM_REG_PPC_TLB2CFG: | 632 | case KVM_REG_PPC_TLB2CFG: |
@@ -678,6 +681,12 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | |||
678 | r = -EINVAL; | 681 | r = -EINVAL; |
679 | break; | 682 | break; |
680 | } | 683 | } |
684 | case KVM_REG_PPC_EPTCFG: { | ||
685 | u32 reg = set_reg_val(id, *val); | ||
686 | if (reg != vcpu->arch.eptcfg) | ||
687 | r = -EINVAL; | ||
688 | break; | ||
689 | } | ||
681 | case KVM_REG_PPC_TLB0CFG: | 690 | case KVM_REG_PPC_TLB0CFG: |
682 | case KVM_REG_PPC_TLB1CFG: | 691 | case KVM_REG_PPC_TLB1CFG: |
683 | case KVM_REG_PPC_TLB2CFG: | 692 | case KVM_REG_PPC_TLB2CFG: |
@@ -875,6 +884,9 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu, | |||
875 | if (has_feature(vcpu, VCPU_FTR_MMU_V2)) { | 884 | if (has_feature(vcpu, VCPU_FTR_MMU_V2)) { |
876 | vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS); | 885 | vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS); |
877 | vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS); | 886 | vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS); |
887 | |||
888 | /* Guest mmu emulation currently doesn't handle E.PT */ | ||
889 | vcpu->arch.eptcfg = 0; | ||
878 | } | 890 | } |
879 | 891 | ||
880 | return 0; | 892 | return 0; |