aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2016-11-16 06:25:20 -0500
committerPaul Mackerras <paulus@ozlabs.org>2016-11-23 17:24:23 -0500
commit7a84084c60545bc47f3339344f1af5f94599c966 (patch)
tree3166ead3661582ce933d80f5f215825f8252fa01
parentabb7c7ddbacd30b9a879491998966771504760bd (diff)
KVM: PPC: Book3S HV: Set partition table rather than SDR1 on POWER9
On POWER9, the SDR1 register (hashed page table base address) is no longer used, and instead the hardware reads the HPT base address and size from the partition table. The partition table entry also contains the bits that specify the page size for the VRMA mapping, which were previously in the LPCR. The VPM0 bit of the LPCR is now reserved; the processor now always uses the VRMA (virtual real-mode area) mechanism for guest real-mode accesses in HPT mode, and the RMO (real-mode offset) mechanism has been dropped. When entering or exiting the guest, we now only have to set the LPIDR (logical partition ID register), not the SDR1 register. There is also no requirement now to transition via a reserved LPID value. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--arch/powerpc/kvm/book3s_hv.c36
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S10
2 files changed, 37 insertions, 9 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 02f9aedbc258..13b6e6154c90 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -54,6 +54,7 @@
54#include <asm/dbell.h> 54#include <asm/dbell.h>
55#include <asm/hmi.h> 55#include <asm/hmi.h>
56#include <asm/pnv-pci.h> 56#include <asm/pnv-pci.h>
57#include <asm/mmu.h>
57#include <linux/gfp.h> 58#include <linux/gfp.h>
58#include <linux/vmalloc.h> 59#include <linux/vmalloc.h>
59#include <linux/highmem.h> 60#include <linux/highmem.h>
@@ -3029,6 +3030,22 @@ static void kvmppc_mmu_destroy_hv(struct kvm_vcpu *vcpu)
3029 return; 3030 return;
3030} 3031}
3031 3032
3033static void kvmppc_setup_partition_table(struct kvm *kvm)
3034{
3035 unsigned long dw0, dw1;
3036
3037 /* PS field - page size for VRMA */
3038 dw0 = ((kvm->arch.vrma_slb_v & SLB_VSID_L) >> 1) |
3039 ((kvm->arch.vrma_slb_v & SLB_VSID_LP) << 1);
3040 /* HTABSIZE and HTABORG fields */
3041 dw0 |= kvm->arch.sdr1;
3042
3043 /* Second dword has GR=0; other fields are unused since UPRT=0 */
3044 dw1 = 0;
3045
3046 mmu_partition_table_set_entry(kvm->arch.lpid, dw0, dw1);
3047}
3048
3032static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) 3049static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
3033{ 3050{
3034 int err = 0; 3051 int err = 0;
@@ -3080,17 +3097,20 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
3080 psize == 0x1000000)) 3097 psize == 0x1000000))
3081 goto out_srcu; 3098 goto out_srcu;
3082 3099
3083 /* Update VRMASD field in the LPCR */
3084 senc = slb_pgsize_encoding(psize); 3100 senc = slb_pgsize_encoding(psize);
3085 kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | 3101 kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T |
3086 (VRMA_VSID << SLB_VSID_SHIFT_1T); 3102 (VRMA_VSID << SLB_VSID_SHIFT_1T);
3087 /* the -4 is to account for senc values starting at 0x10 */
3088 lpcr = senc << (LPCR_VRMASD_SH - 4);
3089
3090 /* Create HPTEs in the hash page table for the VRMA */ 3103 /* Create HPTEs in the hash page table for the VRMA */
3091 kvmppc_map_vrma(vcpu, memslot, porder); 3104 kvmppc_map_vrma(vcpu, memslot, porder);
3092 3105
3093 kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD); 3106 /* Update VRMASD field in the LPCR */
3107 if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
3108 /* the -4 is to account for senc values starting at 0x10 */
3109 lpcr = senc << (LPCR_VRMASD_SH - 4);
3110 kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
3111 } else {
3112 kvmppc_setup_partition_table(kvm);
3113 }
3094 3114
3095 /* Order updates to kvm->arch.lpcr etc. vs. hpte_setup_done */ 3115 /* Order updates to kvm->arch.lpcr etc. vs. hpte_setup_done */
3096 smp_wmb(); 3116 smp_wmb();
@@ -3240,7 +3260,8 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
3240 memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, 3260 memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls,
3241 sizeof(kvm->arch.enabled_hcalls)); 3261 sizeof(kvm->arch.enabled_hcalls));
3242 3262
3243 kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); 3263 if (!cpu_has_feature(CPU_FTR_ARCH_300))
3264 kvm->arch.host_sdr1 = mfspr(SPRN_SDR1);
3244 3265
3245 /* Init LPCR for virtual RMA mode */ 3266 /* Init LPCR for virtual RMA mode */
3246 kvm->arch.host_lpid = mfspr(SPRN_LPID); 3267 kvm->arch.host_lpid = mfspr(SPRN_LPID);
@@ -3253,6 +3274,9 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
3253 /* On POWER8 turn on online bit to enable PURR/SPURR */ 3274 /* On POWER8 turn on online bit to enable PURR/SPURR */
3254 if (cpu_has_feature(CPU_FTR_ARCH_207S)) 3275 if (cpu_has_feature(CPU_FTR_ARCH_207S))
3255 lpcr |= LPCR_ONL; 3276 lpcr |= LPCR_ONL;
3277 /* On POWER9, VPM0 bit is reserved (VPM0=1 behaviour is assumed) */
3278 if (cpu_has_feature(CPU_FTR_ARCH_300))
3279 lpcr &= ~LPCR_VPM0;
3256 kvm->arch.lpcr = lpcr; 3280 kvm->arch.lpcr = lpcr;
3257 3281
3258 /* 3282 /*
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 6f81adb112f1..b2d107d8d215 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -581,12 +581,14 @@ kvmppc_hv_entry:
581 ld r9,VCORE_KVM(r5) /* pointer to struct kvm */ 581 ld r9,VCORE_KVM(r5) /* pointer to struct kvm */
582 cmpwi r6,0 582 cmpwi r6,0
583 bne 10f 583 bne 10f
584 ld r6,KVM_SDR1(r9)
585 lwz r7,KVM_LPID(r9) 584 lwz r7,KVM_LPID(r9)
585BEGIN_FTR_SECTION
586 ld r6,KVM_SDR1(r9)
586 li r0,LPID_RSVD /* switch to reserved LPID */ 587 li r0,LPID_RSVD /* switch to reserved LPID */
587 mtspr SPRN_LPID,r0 588 mtspr SPRN_LPID,r0
588 ptesync 589 ptesync
589 mtspr SPRN_SDR1,r6 /* switch to partition page table */ 590 mtspr SPRN_SDR1,r6 /* switch to partition page table */
591END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
590 mtspr SPRN_LPID,r7 592 mtspr SPRN_LPID,r7
591 isync 593 isync
592 594
@@ -1552,12 +1554,14 @@ kvmhv_switch_to_host:
1552 beq 19f 1554 beq 19f
1553 1555
1554 /* Primary thread switches back to host partition */ 1556 /* Primary thread switches back to host partition */
1555 ld r6,KVM_HOST_SDR1(r4)
1556 lwz r7,KVM_HOST_LPID(r4) 1557 lwz r7,KVM_HOST_LPID(r4)
1558BEGIN_FTR_SECTION
1559 ld r6,KVM_HOST_SDR1(r4)
1557 li r8,LPID_RSVD /* switch to reserved LPID */ 1560 li r8,LPID_RSVD /* switch to reserved LPID */
1558 mtspr SPRN_LPID,r8 1561 mtspr SPRN_LPID,r8
1559 ptesync 1562 ptesync
1560 mtspr SPRN_SDR1,r6 /* switch to partition page table */ 1563 mtspr SPRN_SDR1,r6 /* switch to host page table */
1564END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
1561 mtspr SPRN_LPID,r7 1565 mtspr SPRN_LPID,r7
1562 isync 1566 isync
1563 1567