Skip to content

Commit 769377f

Browse files
committed
KVM: PPC: Book3S HV: Context-switch HFSCR between host and guest on POWER9
This adds code to allow us to use a different value for the HFSCR (Hypervisor Facilities Status and Control Register) when running the guest from that which applies in the host. The reason for doing this is to allow us to trap the msgsndp instruction and related operations in future so that they can be virtualized. We also save the value of HFSCR when a hypervisor facility unavailable interrupt occurs, because the high byte of HFSCR indicates which facility the guest attempted to access. We save and restore the host value on guest entry/exit because some bits of it affect host userspace execution. We only do all this on POWER9, not on POWER8, because we are not intending to virtualize any of the facilities controlled by HFSCR on POWER8. In particular, the HFSCR bit that controls execution of msgsndp and related operations does not exist on POWER8. The HFSCR doesn't exist at all on POWER7. Signed-off-by: Paul Mackerras <[email protected]>
1 parent 1da4e2f commit 769377f

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

arch/powerpc/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ struct kvm_vcpu_arch {
566566
ulong wort;
567567
ulong tid;
568568
ulong psscr;
569+
ulong hfscr;
569570
ulong shadow_srr1;
570571
#endif
571572
u32 vrsave; /* also USPRG0 */

arch/powerpc/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ int main(void)
542542
OFFSET(VCPU_WORT, kvm_vcpu, arch.wort);
543543
OFFSET(VCPU_TID, kvm_vcpu, arch.tid);
544544
OFFSET(VCPU_PSSCR, kvm_vcpu, arch.psscr);
545+
OFFSET(VCPU_HFSCR, kvm_vcpu, arch.hfscr);
545546
OFFSET(VCORE_ENTRY_EXIT, kvmppc_vcore, entry_exit_map);
546547
OFFSET(VCORE_IN_GUEST, kvmppc_vcore, in_guest);
547548
OFFSET(VCORE_NAPPING_THREADS, kvmppc_vcore, napping_threads);

arch/powerpc/kvm/book3s_hv.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,16 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,
18251825
vcpu->arch.busy_preempt = TB_NIL;
18261826
vcpu->arch.intr_msr = MSR_SF | MSR_ME;
18271827

1828+
/*
1829+
* Set the default HFSCR for the guest from the host value.
1830+
* This value is only used on POWER9.
1831+
* On POWER9 DD1, TM doesn't work, so we make sure to
1832+
* prevent the guest from using it.
1833+
*/
1834+
vcpu->arch.hfscr = mfspr(SPRN_HFSCR);
1835+
if (!cpu_has_feature(CPU_FTR_TM))
1836+
vcpu->arch.hfscr &= ~HFSCR_TM;
1837+
18281838
kvmppc_mmu_book3s_hv_init(vcpu);
18291839

18301840
vcpu->arch.state = KVMPPC_VCPU_NOTREADY;

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
4545
#define NAPPING_NOVCPU 2
4646

4747
/* Stack frame offsets for kvmppc_hv_entry */
48-
#define SFS 144
48+
#define SFS 160
4949
#define STACK_SLOT_TRAP (SFS-4)
5050
#define STACK_SLOT_TID (SFS-16)
5151
#define STACK_SLOT_PSSCR (SFS-24)
@@ -54,6 +54,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
5454
#define STACK_SLOT_CIABR (SFS-48)
5555
#define STACK_SLOT_DAWR (SFS-56)
5656
#define STACK_SLOT_DAWRX (SFS-64)
57+
#define STACK_SLOT_HFSCR (SFS-72)
5758

5859
/*
5960
* Call kvmppc_hv_entry in real mode.
@@ -769,6 +770,8 @@ BEGIN_FTR_SECTION
769770
std r6, STACK_SLOT_PSSCR(r1)
770771
std r7, STACK_SLOT_PID(r1)
771772
std r8, STACK_SLOT_IAMR(r1)
773+
mfspr r5, SPRN_HFSCR
774+
std r5, STACK_SLOT_HFSCR(r1)
772775
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
773776
BEGIN_FTR_SECTION
774777
mfspr r5, SPRN_CIABR
@@ -920,8 +923,10 @@ FTR_SECTION_ELSE
920923
ld r5, VCPU_TID(r4)
921924
ld r6, VCPU_PSSCR(r4)
922925
oris r6, r6, PSSCR_EC@h /* This makes stop trap to HV */
926+
ld r7, VCPU_HFSCR(r4)
923927
mtspr SPRN_TIDR, r5
924928
mtspr SPRN_PSSCR, r6
929+
mtspr SPRN_HFSCR, r7
925930
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
926931
8:
927932

@@ -1294,6 +1299,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
12941299
beq 4f
12951300
b guest_exit_cont
12961301
3:
1302+
/* If it's a hypervisor facility unavailable interrupt, save HFSCR */
1303+
cmpwi r12, BOOK3S_INTERRUPT_H_FAC_UNAVAIL
1304+
bne 14f
1305+
mfspr r3, SPRN_HFSCR
1306+
std r3, VCPU_HFSCR(r9)
1307+
b guest_exit_cont
1308+
14:
12971309
/* External interrupt ? */
12981310
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
12991311
bne+ guest_exit_cont
@@ -1537,6 +1549,9 @@ FTR_SECTION_ELSE
15371549
rldicl r6, r6, 4, 50 /* r6 &= PSSCR_GUEST_VIS */
15381550
rotldi r6, r6, 60
15391551
std r6, VCPU_PSSCR(r9)
1552+
/* Restore host HFSCR value */
1553+
ld r7, STACK_SLOT_HFSCR(r1)
1554+
mtspr SPRN_HFSCR, r7
15401555
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
15411556
/*
15421557
* Restore various registers to 0, where non-zero values

0 commit comments

Comments
 (0)