Skip to content

Commit 1bc3fe8

Browse files
committed
KVM: PPC: Book3S HV: Enable guests to use large decrementer mode on POWER9
This allows userspace (e.g. QEMU) to enable large decrementer mode for the guest when running on a POWER9 host, by setting the LPCR_LD bit in the guest LPCR value. With this, the guest exit code saves 64 bits of the guest DEC value on exit. Other places that use the guest DEC value check the LPCR_LD bit in the guest LPCR value, and if it is set, omit the 32-bit sign extension that would otherwise be done. This doesn't change the DEC emulation used by PR KVM because PR KVM is not supported on POWER9 yet. This is partly based on an earlier patch by Oliver O'Halloran. Signed-off-by: Paul Mackerras <[email protected]>
1 parent 3d3efb6 commit 1bc3fe8

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

arch/powerpc/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ struct kvm_vcpu_arch {
579579
ulong mcsrr0;
580580
ulong mcsrr1;
581581
ulong mcsr;
582-
u32 dec;
582+
ulong dec;
583583
#ifdef CONFIG_BOOKE
584584
u32 decar;
585585
#endif

arch/powerpc/kvm/book3s_hv.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,12 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr,
11431143
mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
11441144
if (cpu_has_feature(CPU_FTR_ARCH_207S))
11451145
mask |= LPCR_AIL;
1146+
/*
1147+
* On POWER9, allow userspace to enable large decrementer for the
1148+
* guest, whether or not the host has it enabled.
1149+
*/
1150+
if (cpu_has_feature(CPU_FTR_ARCH_300))
1151+
mask |= LPCR_LD;
11461152

11471153
/* Broken 32-bit version of LPCR must not clear top bits */
11481154
if (preserve_top32)

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
936936
mftb r7
937937
subf r3,r7,r8
938938
mtspr SPRN_DEC,r3
939-
stw r3,VCPU_DEC(r4)
939+
std r3,VCPU_DEC(r4)
940940

941941
ld r5, VCPU_SPRG0(r4)
942942
ld r6, VCPU_SPRG1(r4)
@@ -1048,7 +1048,13 @@ kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
10481048
li r0, BOOK3S_INTERRUPT_EXTERNAL
10491049
bne cr1, 12f
10501050
mfspr r0, SPRN_DEC
1051-
cmpwi r0, 0
1051+
BEGIN_FTR_SECTION
1052+
/* On POWER9 check whether the guest has large decrementer enabled */
1053+
andis. r8, r8, LPCR_LD@h
1054+
bne 15f
1055+
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
1056+
extsw r0, r0
1057+
15: cmpdi r0, 0
10521058
li r0, BOOK3S_INTERRUPT_DECREMENTER
10531059
bge 5f
10541060

@@ -1475,12 +1481,18 @@ mc_cont:
14751481
mtspr SPRN_SPURR,r4
14761482

14771483
/* Save DEC */
1484+
ld r3, HSTATE_KVM_VCORE(r13)
14781485
mfspr r5,SPRN_DEC
14791486
mftb r6
1487+
/* On P9, if the guest has large decr enabled, don't sign extend */
1488+
BEGIN_FTR_SECTION
1489+
ld r4, VCORE_LPCR(r3)
1490+
andis. r4, r4, LPCR_LD@h
1491+
bne 16f
1492+
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
14801493
extsw r5,r5
1481-
add r5,r5,r6
1494+
16: add r5,r5,r6
14821495
/* r5 is a guest timebase value here, convert to host TB */
1483-
ld r3,HSTATE_KVM_VCORE(r13)
14841496
ld r4,VCORE_TB_OFFSET(r3)
14851497
subf r5,r4,r5
14861498
std r5,VCPU_DEC_EXPIRES(r9)
@@ -2402,8 +2414,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
24022414
mfspr r3, SPRN_DEC
24032415
mfspr r4, SPRN_HDEC
24042416
mftb r5
2417+
BEGIN_FTR_SECTION
2418+
/* On P9 check whether the guest has large decrementer mode enabled */
2419+
ld r6, HSTATE_KVM_VCORE(r13)
2420+
ld r6, VCORE_LPCR(r6)
2421+
andis. r6, r6, LPCR_LD@h
2422+
bne 68f
2423+
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
24052424
extsw r3, r3
2406-
EXTEND_HDEC(r4)
2425+
68: EXTEND_HDEC(r4)
24072426
cmpd r3, r4
24082427
ble 67f
24092428
mtspr SPRN_DEC, r4

arch/powerpc/kvm/emulate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
3939
unsigned long dec_nsec;
4040
unsigned long long dec_time;
4141

42-
pr_debug("mtDEC: %x\n", vcpu->arch.dec);
42+
pr_debug("mtDEC: %lx\n", vcpu->arch.dec);
4343
hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
4444

4545
#ifdef CONFIG_PPC_BOOK3S
@@ -109,7 +109,7 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
109109
case SPRN_TBWU: break;
110110

111111
case SPRN_DEC:
112-
vcpu->arch.dec = spr_val;
112+
vcpu->arch.dec = (u32) spr_val;
113113
kvmppc_emulate_dec(vcpu);
114114
break;
115115

0 commit comments

Comments
 (0)