summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Niethe <jniethe5@gmail.com>2019-09-16 20:46:05 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2019-09-20 18:36:53 -0400
commit13c7bb3c57dcfe779ea5b4b083f6c47753cc5327 (patch)
treeb1f09704685bd96151bf3f6882100d5ef0112069
parentc6fadabb2868f817299ddb338ac15885e25d12d2 (diff)
powerpc/64s: Set reserved PCR bits
Currently the reserved bits of the Processor Compatibility Register (PCR) are cleared as per the Programming Note in Section 1.3.3 of version 3.0B of the Power ISA. This causes all new architecture features to be made available when running on newer processors with new architecture features added to the PCR as bits must be set to disable a given feature. For example to disable new features added as part of Version 2.07 of the ISA the corresponding bit in the PCR needs to be set. As new processor features generally require explicit kernel support they should be disabled until such support is implemented. Therefore kernels should set all unknown/reserved bits in the PCR such that any new architecture features which the kernel does not currently know about get disabled. An update is planned to the ISA to clarify that the PCR is an exception to the Programming Note on reserved bits in Section 1.3.3. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Tested-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190917004605.22471-2-alistair@popple.id.au
-rw-r--r--arch/powerpc/include/asm/reg.h3
-rw-r--r--arch/powerpc/kernel/cpu_setup_power.S6
-rw-r--r--arch/powerpc/kernel/dt_cpu_ftrs.c3
-rw-r--r--arch/powerpc/kvm/book3s_hv.c11
-rw-r--r--arch/powerpc/kvm/book3s_hv_nested.c6
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S10
6 files changed, 27 insertions, 12 deletions
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 931939af95d1..b3cbb1136bce 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -478,6 +478,7 @@
478#define PCR_VEC_DIS (__MASK(63-0)) /* Vec. disable (bit NA since POWER8) */ 478#define PCR_VEC_DIS (__MASK(63-0)) /* Vec. disable (bit NA since POWER8) */
479#define PCR_VSX_DIS (__MASK(63-1)) /* VSX disable (bit NA since POWER8) */ 479#define PCR_VSX_DIS (__MASK(63-1)) /* VSX disable (bit NA since POWER8) */
480#define PCR_TM_DIS (__MASK(63-2)) /* Trans. memory disable (POWER8) */ 480#define PCR_TM_DIS (__MASK(63-2)) /* Trans. memory disable (POWER8) */
481#define PCR_HIGH_BITS (PCR_VEC_DIS | PCR_VSX_DIS | PCR_TM_DIS)
481/* 482/*
482 * These bits are used in the function kvmppc_set_arch_compat() to specify and 483 * These bits are used in the function kvmppc_set_arch_compat() to specify and
483 * determine both the compatibility level which we want to emulate and the 484 * determine both the compatibility level which we want to emulate and the
@@ -486,6 +487,8 @@
486#define PCR_ARCH_207 0x8 /* Architecture 2.07 */ 487#define PCR_ARCH_207 0x8 /* Architecture 2.07 */
487#define PCR_ARCH_206 0x4 /* Architecture 2.06 */ 488#define PCR_ARCH_206 0x4 /* Architecture 2.06 */
488#define PCR_ARCH_205 0x2 /* Architecture 2.05 */ 489#define PCR_ARCH_205 0x2 /* Architecture 2.05 */
490#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205)
491#define PCR_MASK ~(PCR_HIGH_BITS | PCR_LOW_BITS) /* PCR Reserved Bits */
489#define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */ 492#define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */
490#define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */ 493#define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */
491#define SPRN_TLBVPNR 0x155 /* P7 TLB control register */ 494#define SPRN_TLBVPNR 0x155 /* P7 TLB control register */
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 3239a9fe6c1c..a460298c7ddb 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -23,6 +23,7 @@ _GLOBAL(__setup_cpu_power7)
23 beqlr 23 beqlr
24 li r0,0 24 li r0,0
25 mtspr SPRN_LPID,r0 25 mtspr SPRN_LPID,r0
26 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
26 mtspr SPRN_PCR,r0 27 mtspr SPRN_PCR,r0
27 mfspr r3,SPRN_LPCR 28 mfspr r3,SPRN_LPCR
28 li r4,(LPCR_LPES1 >> LPCR_LPES_SH) 29 li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
@@ -37,6 +38,7 @@ _GLOBAL(__restore_cpu_power7)
37 beqlr 38 beqlr
38 li r0,0 39 li r0,0
39 mtspr SPRN_LPID,r0 40 mtspr SPRN_LPID,r0
41 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
40 mtspr SPRN_PCR,r0 42 mtspr SPRN_PCR,r0
41 mfspr r3,SPRN_LPCR 43 mfspr r3,SPRN_LPCR
42 li r4,(LPCR_LPES1 >> LPCR_LPES_SH) 44 li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
@@ -54,6 +56,7 @@ _GLOBAL(__setup_cpu_power8)
54 beqlr 56 beqlr
55 li r0,0 57 li r0,0
56 mtspr SPRN_LPID,r0 58 mtspr SPRN_LPID,r0
59 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
57 mtspr SPRN_PCR,r0 60 mtspr SPRN_PCR,r0
58 mfspr r3,SPRN_LPCR 61 mfspr r3,SPRN_LPCR
59 ori r3, r3, LPCR_PECEDH 62 ori r3, r3, LPCR_PECEDH
@@ -76,6 +79,7 @@ _GLOBAL(__restore_cpu_power8)
76 beqlr 79 beqlr
77 li r0,0 80 li r0,0
78 mtspr SPRN_LPID,r0 81 mtspr SPRN_LPID,r0
82 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
79 mtspr SPRN_PCR,r0 83 mtspr SPRN_PCR,r0
80 mfspr r3,SPRN_LPCR 84 mfspr r3,SPRN_LPCR
81 ori r3, r3, LPCR_PECEDH 85 ori r3, r3, LPCR_PECEDH
@@ -98,6 +102,7 @@ _GLOBAL(__setup_cpu_power9)
98 mtspr SPRN_PSSCR,r0 102 mtspr SPRN_PSSCR,r0
99 mtspr SPRN_LPID,r0 103 mtspr SPRN_LPID,r0
100 mtspr SPRN_PID,r0 104 mtspr SPRN_PID,r0
105 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
101 mtspr SPRN_PCR,r0 106 mtspr SPRN_PCR,r0
102 mfspr r3,SPRN_LPCR 107 mfspr r3,SPRN_LPCR
103 LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) 108 LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
@@ -123,6 +128,7 @@ _GLOBAL(__restore_cpu_power9)
123 mtspr SPRN_PSSCR,r0 128 mtspr SPRN_PSSCR,r0
124 mtspr SPRN_LPID,r0 129 mtspr SPRN_LPID,r0
125 mtspr SPRN_PID,r0 130 mtspr SPRN_PID,r0
131 LOAD_REG_IMMEDIATE(r0, PCR_MASK)
126 mtspr SPRN_PCR,r0 132 mtspr SPRN_PCR,r0
127 mfspr r3,SPRN_LPCR 133 mfspr r3,SPRN_LPCR
128 LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) 134 LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index bd95318d2202..bceee2fde885 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -101,7 +101,7 @@ static void __restore_cpu_cpufeatures(void)
101 if (hv_mode) { 101 if (hv_mode) {
102 mtspr(SPRN_LPID, 0); 102 mtspr(SPRN_LPID, 0);
103 mtspr(SPRN_HFSCR, system_registers.hfscr); 103 mtspr(SPRN_HFSCR, system_registers.hfscr);
104 mtspr(SPRN_PCR, 0); 104 mtspr(SPRN_PCR, PCR_MASK);
105 } 105 }
106 mtspr(SPRN_FSCR, system_registers.fscr); 106 mtspr(SPRN_FSCR, system_registers.fscr);
107 107
@@ -144,6 +144,7 @@ static void __init cpufeatures_setup_cpu(void)
144 mtspr(SPRN_HFSCR, 0); 144 mtspr(SPRN_HFSCR, 0);
145 } 145 }
146 mtspr(SPRN_FSCR, 0); 146 mtspr(SPRN_FSCR, 0);
147 mtspr(SPRN_PCR, PCR_MASK);
147 148
148 /* 149 /*
149 * LPCR does not get cleared, to match behaviour with secondaries 150 * LPCR does not get cleared, to match behaviour with secondaries
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index efd8f93bc9dc..709cf1fd4cf4 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -401,8 +401,11 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
401 401
402 spin_lock(&vc->lock); 402 spin_lock(&vc->lock);
403 vc->arch_compat = arch_compat; 403 vc->arch_compat = arch_compat;
404 /* Set all PCR bits for which guest_pcr_bit <= bit < host_pcr_bit */ 404 /*
405 vc->pcr = host_pcr_bit - guest_pcr_bit; 405 * Set all PCR bits for which guest_pcr_bit <= bit < host_pcr_bit
406 * Also set all reserved PCR bits
407 */
408 vc->pcr = (host_pcr_bit - guest_pcr_bit) | PCR_MASK;
406 spin_unlock(&vc->lock); 409 spin_unlock(&vc->lock);
407 410
408 return 0; 411 return 0;
@@ -3410,7 +3413,7 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit,
3410 } 3413 }
3411 3414
3412 if (vc->pcr) 3415 if (vc->pcr)
3413 mtspr(SPRN_PCR, vc->pcr); 3416 mtspr(SPRN_PCR, vc->pcr | PCR_MASK);
3414 mtspr(SPRN_DPDES, vc->dpdes); 3417 mtspr(SPRN_DPDES, vc->dpdes);
3415 mtspr(SPRN_VTB, vc->vtb); 3418 mtspr(SPRN_VTB, vc->vtb);
3416 3419
@@ -3490,7 +3493,7 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit,
3490 vc->vtb = mfspr(SPRN_VTB); 3493 vc->vtb = mfspr(SPRN_VTB);
3491 mtspr(SPRN_DPDES, 0); 3494 mtspr(SPRN_DPDES, 0);
3492 if (vc->pcr) 3495 if (vc->pcr)
3493 mtspr(SPRN_PCR, 0); 3496 mtspr(SPRN_PCR, PCR_MASK);
3494 3497
3495 if (vc->tb_offset_applied) { 3498 if (vc->tb_offset_applied) {
3496 u64 new_tb = mftb() - vc->tb_offset_applied; 3499 u64 new_tb = mftb() - vc->tb_offset_applied;
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index fff90f2c3de2..cdf30c6eaf54 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -29,7 +29,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
29{ 29{
30 struct kvmppc_vcore *vc = vcpu->arch.vcore; 30 struct kvmppc_vcore *vc = vcpu->arch.vcore;
31 31
32 hr->pcr = vc->pcr; 32 hr->pcr = vc->pcr | PCR_MASK;
33 hr->dpdes = vc->dpdes; 33 hr->dpdes = vc->dpdes;
34 hr->hfscr = vcpu->arch.hfscr; 34 hr->hfscr = vcpu->arch.hfscr;
35 hr->tb_offset = vc->tb_offset; 35 hr->tb_offset = vc->tb_offset;
@@ -65,7 +65,7 @@ static void byteswap_hv_regs(struct hv_guest_state *hr)
65 hr->lpid = swab32(hr->lpid); 65 hr->lpid = swab32(hr->lpid);
66 hr->vcpu_token = swab32(hr->vcpu_token); 66 hr->vcpu_token = swab32(hr->vcpu_token);
67 hr->lpcr = swab64(hr->lpcr); 67 hr->lpcr = swab64(hr->lpcr);
68 hr->pcr = swab64(hr->pcr); 68 hr->pcr = swab64(hr->pcr) | PCR_MASK;
69 hr->amor = swab64(hr->amor); 69 hr->amor = swab64(hr->amor);
70 hr->dpdes = swab64(hr->dpdes); 70 hr->dpdes = swab64(hr->dpdes);
71 hr->hfscr = swab64(hr->hfscr); 71 hr->hfscr = swab64(hr->hfscr);
@@ -148,7 +148,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
148{ 148{
149 struct kvmppc_vcore *vc = vcpu->arch.vcore; 149 struct kvmppc_vcore *vc = vcpu->arch.vcore;
150 150
151 vc->pcr = hr->pcr; 151 vc->pcr = hr->pcr | PCR_MASK;
152 vc->dpdes = hr->dpdes; 152 vc->dpdes = hr->dpdes;
153 vcpu->arch.hfscr = hr->hfscr; 153 vcpu->arch.hfscr = hr->hfscr;
154 vcpu->arch.dawr = hr->dawr0; 154 vcpu->arch.dawr = hr->dawr0;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 9a05b0d932ef..74a9cfe84aee 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -644,8 +644,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
644 644
645 /* Load guest PCR value to select appropriate compat mode */ 645 /* Load guest PCR value to select appropriate compat mode */
64637: ld r7, VCORE_PCR(r5) 64637: ld r7, VCORE_PCR(r5)
647 cmpdi r7, 0 647 LOAD_REG_IMMEDIATE(r6, PCR_MASK)
648 cmpld r7, r6
648 beq 38f 649 beq 38f
650 or r7, r7, r6
649 mtspr SPRN_PCR, r7 651 mtspr SPRN_PCR, r7
65038: 65238:
651 653
@@ -1913,10 +1915,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1913 1915
1914 /* Reset PCR */ 1916 /* Reset PCR */
1915 ld r0, VCORE_PCR(r5) 1917 ld r0, VCORE_PCR(r5)
1916 cmpdi r0, 0 1918 LOAD_REG_IMMEDIATE(r6, PCR_MASK)
1919 cmpld r0, r6
1917 beq 18f 1920 beq 18f
1918 li r0, 0 1921 mtspr SPRN_PCR, r6
1919 mtspr SPRN_PCR, r0
192018: 192218:
1921 /* Signal secondary CPUs to continue */ 1923 /* Signal secondary CPUs to continue */
1922 stb r0,VCORE_IN_GUEST(r5) 1924 stb r0,VCORE_IN_GUEST(r5)