aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2016-11-17 21:11:42 -0500
committerPaul Mackerras <paulus@ozlabs.org>2016-11-23 17:24:23 -0500
commite9cf1e085647b433ccd98582681b17121ecfdc21 (patch)
tree6147ebf857ac4c8ff7439c0f2d038745ea6763be
parent83677f551e0a6ad43061053e7d6208abcd2707f0 (diff)
KVM: PPC: Book3S HV: Add new POWER9 guest-accessible SPRs
This adds code to handle two new guest-accessible special-purpose registers on POWER9: TIDR (thread ID register) and PSSCR (processor stop status and control register). They are context-switched between host and guest, and the guest values can be read and set via the one_reg interface. The PSSCR contains some fields which are guest-accessible and some which are only accessible in hypervisor mode. We only allow the guest-accessible fields to be read or set by userspace. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--Documentation/virtual/kvm/api.txt2
-rw-r--r--arch/powerpc/include/asm/kvm_host.h2
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv.c12
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S39
6 files changed, 59 insertions, 2 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index a7596e9fdf06..8a5ebd118313 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2023,6 +2023,8 @@ registers, find a list below:
2023 PPC | KVM_REG_PPC_WORT | 64 2023 PPC | KVM_REG_PPC_WORT | 64
2024 PPC | KVM_REG_PPC_SPRG9 | 64 2024 PPC | KVM_REG_PPC_SPRG9 | 64
2025 PPC | KVM_REG_PPC_DBSR | 32 2025 PPC | KVM_REG_PPC_DBSR | 32
2026 PPC | KVM_REG_PPC_TIDR | 64
2027 PPC | KVM_REG_PPC_PSSCR | 64
2026 PPC | KVM_REG_PPC_TM_GPR0 | 64 2028 PPC | KVM_REG_PPC_TM_GPR0 | 64
2027 ... 2029 ...
2028 PPC | KVM_REG_PPC_TM_GPR31 | 64 2030 PPC | KVM_REG_PPC_TM_GPR31 | 64
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 0e584ee57730..9556de61b1bb 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -517,6 +517,8 @@ struct kvm_vcpu_arch {
517 ulong tcscr; 517 ulong tcscr;
518 ulong acop; 518 ulong acop;
519 ulong wort; 519 ulong wort;
520 ulong tid;
521 ulong psscr;
520 ulong shadow_srr1; 522 ulong shadow_srr1;
521#endif 523#endif
522 u32 vrsave; /* also USPRG0 */ 524 u32 vrsave; /* also USPRG0 */
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 0fb1326c3ea2..3603b6f51b11 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -573,6 +573,10 @@ struct kvm_get_htab_header {
573#define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba) 573#define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
574#define KVM_REG_PPC_DBSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb) 574#define KVM_REG_PPC_DBSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb)
575 575
576/* POWER9 registers */
577#define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
578#define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
579
576/* Transactional Memory checkpointed state: 580/* Transactional Memory checkpointed state:
577 * This is all GPRs, all VSX regs and a subset of SPRs 581 * This is all GPRs, all VSX regs and a subset of SPRs
578 */ 582 */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index c833d88c423d..a4f6d5e32a81 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -548,6 +548,8 @@ int main(void)
548 DEFINE(VCPU_TCSCR, offsetof(struct kvm_vcpu, arch.tcscr)); 548 DEFINE(VCPU_TCSCR, offsetof(struct kvm_vcpu, arch.tcscr));
549 DEFINE(VCPU_ACOP, offsetof(struct kvm_vcpu, arch.acop)); 549 DEFINE(VCPU_ACOP, offsetof(struct kvm_vcpu, arch.acop));
550 DEFINE(VCPU_WORT, offsetof(struct kvm_vcpu, arch.wort)); 550 DEFINE(VCPU_WORT, offsetof(struct kvm_vcpu, arch.wort));
551 DEFINE(VCPU_TID, offsetof(struct kvm_vcpu, arch.tid));
552 DEFINE(VCPU_PSSCR, offsetof(struct kvm_vcpu, arch.psscr));
551 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_map)); 553 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_map));
552 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest)); 554 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
553 DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads)); 555 DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads));
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 13b6e6154c90..14eeacc82336 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1230,6 +1230,12 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
1230 case KVM_REG_PPC_WORT: 1230 case KVM_REG_PPC_WORT:
1231 *val = get_reg_val(id, vcpu->arch.wort); 1231 *val = get_reg_val(id, vcpu->arch.wort);
1232 break; 1232 break;
1233 case KVM_REG_PPC_TIDR:
1234 *val = get_reg_val(id, vcpu->arch.tid);
1235 break;
1236 case KVM_REG_PPC_PSSCR:
1237 *val = get_reg_val(id, vcpu->arch.psscr);
1238 break;
1233 case KVM_REG_PPC_VPA_ADDR: 1239 case KVM_REG_PPC_VPA_ADDR:
1234 spin_lock(&vcpu->arch.vpa_update_lock); 1240 spin_lock(&vcpu->arch.vpa_update_lock);
1235 *val = get_reg_val(id, vcpu->arch.vpa.next_gpa); 1241 *val = get_reg_val(id, vcpu->arch.vpa.next_gpa);
@@ -1431,6 +1437,12 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
1431 case KVM_REG_PPC_WORT: 1437 case KVM_REG_PPC_WORT:
1432 vcpu->arch.wort = set_reg_val(id, *val); 1438 vcpu->arch.wort = set_reg_val(id, *val);
1433 break; 1439 break;
1440 case KVM_REG_PPC_TIDR:
1441 vcpu->arch.tid = set_reg_val(id, *val);
1442 break;
1443 case KVM_REG_PPC_PSSCR:
1444 vcpu->arch.psscr = set_reg_val(id, *val) & PSSCR_GUEST_VIS;
1445 break;
1434 case KVM_REG_PPC_VPA_ADDR: 1446 case KVM_REG_PPC_VPA_ADDR:
1435 addr = set_reg_val(id, *val); 1447 addr = set_reg_val(id, *val);
1436 r = -EINVAL; 1448 r = -EINVAL;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index c7dd251ac05d..499be609c80e 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -523,6 +523,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
523 * * 523 * *
524 *****************************************************************************/ 524 *****************************************************************************/
525 525
526/* Stack frame offsets */
527#define STACK_SLOT_TID (112-16)
528#define STACK_SLOT_PSSCR (112-24)
529
526.global kvmppc_hv_entry 530.global kvmppc_hv_entry
527kvmppc_hv_entry: 531kvmppc_hv_entry:
528 532
@@ -700,6 +704,14 @@ kvmppc_got_guest:
700 mtspr SPRN_PURR,r7 704 mtspr SPRN_PURR,r7
701 mtspr SPRN_SPURR,r8 705 mtspr SPRN_SPURR,r8
702 706
707 /* Save host values of some registers */
708BEGIN_FTR_SECTION
709 mfspr r5, SPRN_TIDR
710 mfspr r6, SPRN_PSSCR
711 std r5, STACK_SLOT_TID(r1)
712 std r6, STACK_SLOT_PSSCR(r1)
713END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
714
703BEGIN_FTR_SECTION 715BEGIN_FTR_SECTION
704 /* Set partition DABR */ 716 /* Set partition DABR */
705 /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */ 717 /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
@@ -824,6 +836,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
824 mtspr SPRN_PID, r7 836 mtspr SPRN_PID, r7
825 mtspr SPRN_WORT, r8 837 mtspr SPRN_WORT, r8
826BEGIN_FTR_SECTION 838BEGIN_FTR_SECTION
839 /* POWER8-only registers */
827 ld r5, VCPU_TCSCR(r4) 840 ld r5, VCPU_TCSCR(r4)
828 ld r6, VCPU_ACOP(r4) 841 ld r6, VCPU_ACOP(r4)
829 ld r7, VCPU_CSIGR(r4) 842 ld r7, VCPU_CSIGR(r4)
@@ -832,7 +845,14 @@ BEGIN_FTR_SECTION
832 mtspr SPRN_ACOP, r6 845 mtspr SPRN_ACOP, r6
833 mtspr SPRN_CSIGR, r7 846 mtspr SPRN_CSIGR, r7
834 mtspr SPRN_TACR, r8 847 mtspr SPRN_TACR, r8
835END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) 848FTR_SECTION_ELSE
849 /* POWER9-only registers */
850 ld r5, VCPU_TID(r4)
851 ld r6, VCPU_PSSCR(r4)
852 oris r6, r6, PSSCR_EC@h /* This makes stop trap to HV */
853 mtspr SPRN_TIDR, r5
854 mtspr SPRN_PSSCR, r6
855ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
8368: 8568:
837 857
838 /* 858 /*
@@ -1362,7 +1382,14 @@ BEGIN_FTR_SECTION
1362 std r6, VCPU_ACOP(r9) 1382 std r6, VCPU_ACOP(r9)
1363 std r7, VCPU_CSIGR(r9) 1383 std r7, VCPU_CSIGR(r9)
1364 std r8, VCPU_TACR(r9) 1384 std r8, VCPU_TACR(r9)
1365END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) 1385FTR_SECTION_ELSE
1386 mfspr r5, SPRN_TIDR
1387 mfspr r6, SPRN_PSSCR
1388 std r5, VCPU_TID(r9)
1389 rldicl r6, r6, 4, 50 /* r6 &= PSSCR_GUEST_VIS */
1390 rotldi r6, r6, 60
1391 std r6, VCPU_PSSCR(r9)
1392ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
1366 /* 1393 /*
1367 * Restore various registers to 0, where non-zero values 1394 * Restore various registers to 0, where non-zero values
1368 * set by the guest could disrupt the host. 1395 * set by the guest could disrupt the host.
@@ -1531,6 +1558,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1531 slbia 1558 slbia
1532 ptesync 1559 ptesync
1533 1560
1561 /* Restore host values of some registers */
1562BEGIN_FTR_SECTION
1563 ld r5, STACK_SLOT_TID(r1)
1564 ld r6, STACK_SLOT_PSSCR(r1)
1565 mtspr SPRN_TIDR, r5
1566 mtspr SPRN_PSSCR, r6
1567END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
1568
1534 /* 1569 /*
1535 * POWER7/POWER8 guest -> host partition switch code. 1570 * POWER7/POWER8 guest -> host partition switch code.
1536 * We don't have to lock against tlbies but we do 1571 * We don't have to lock against tlbies but we do