Skip to content

Commit 1aa940d

Browse files
committed
Merge branch 'topic/ppc-kvm' into next
Merge some more commits from our KVM topic branch. In particular this brings in some commits that depend on a new capability that was merged via the KVM tree for v5.18.
2 parents f82da16 + f771b55 commit 1aa940d

File tree

9 files changed

+142
-18
lines changed

9 files changed

+142
-18
lines changed

arch/powerpc/include/asm/setup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ void setup_panic(void);
2828
#define ARCH_PANIC_TIMEOUT 180
2929

3030
#ifdef CONFIG_PPC_PSERIES
31+
extern bool pseries_reloc_on_exception(void);
3132
extern bool pseries_enable_reloc_on_exc(void);
3233
extern void pseries_disable_reloc_on_exc(void);
3334
extern void pseries_big_endian_exceptions(void);
3435
void __init pseries_little_endian_exceptions(void);
3536
#else
37+
static inline bool pseries_reloc_on_exception(void) { return false; }
3638
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
3739
static inline void pseries_disable_reloc_on_exc(void) {}
3840
static inline void pseries_big_endian_exceptions(void) {}

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,10 @@ __start_interrupts:
809809
* - MSR_EE|MSR_RI is clear (no reentrant exceptions)
810810
* - Standard kernel environment is set up (stack, paca, etc)
811811
*
812+
* KVM:
813+
* These interrupts do not elevate HV 0->1, so HV is not involved. PR KVM
814+
* ensures that FSCR[SCV] is disabled whenever it has to force AIL off.
815+
*
812816
* Call convention:
813817
*
814818
* syscall register convention is in Documentation/powerpc/syscall64-abi.rst

arch/powerpc/kernel/setup_64.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,34 @@ static void __init configure_exceptions(void)
196196

197197
/* Under a PAPR hypervisor, we need hypercalls */
198198
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
199+
/*
200+
* - PR KVM does not support AIL mode interrupts in the host
201+
* while a PR guest is running.
202+
*
203+
* - SCV system call interrupt vectors are only implemented for
204+
* AIL mode interrupts.
205+
*
206+
* - On pseries, AIL mode can only be enabled and disabled
207+
* system-wide so when a PR VM is created on a pseries host,
208+
* all CPUs of the host are set to AIL=0 mode.
209+
*
210+
* - Therefore host CPUs must not execute scv while a PR VM
211+
* exists.
212+
*
213+
* - SCV support can not be disabled dynamically because the
214+
* feature is advertised to host userspace. Disabling the
215+
* facility and emulating it would be possible but is not
216+
* implemented.
217+
*
218+
* - So SCV support is blanket disabled if PR KVM could possibly
219+
* run. That is, PR support compiled in, booting on pseries
220+
* with hash MMU.
221+
*/
222+
if (IS_ENABLED(CONFIG_KVM_BOOK3S_PR_POSSIBLE) && !radix_enabled()) {
223+
init_task.thread.fscr &= ~FSCR_SCV;
224+
cur_cpu_spec->cpu_user_features2 &= ~PPC_FEATURE2_SCV;
225+
}
226+
199227
/* Enable AIL if possible */
200228
if (!pseries_enable_reloc_on_exc()) {
201229
init_task.thread.fscr &= ~FSCR_SCV;

arch/powerpc/kvm/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,21 @@ config KVM_BOOK3S_64_PR
112112
guest in user mode (problem state) and emulating all
113113
privileged instructions and registers.
114114

115+
This is only available for hash MMU mode and only supports
116+
guests that use hash MMU mode.
117+
115118
This is not as fast as using hypervisor mode, but works on
116119
machines where hypervisor mode is not available or not usable,
117120
and can emulate processors that are different from the host
118121
processor, including emulating 32-bit processors on a 64-bit
119122
host.
120123

124+
Selecting this option will cause the SCV facility to be
125+
disabled when the kernel is booted on the pseries platform in
126+
hash MMU mode (regardless of PR VMs running). When any PR VMs
127+
are running, "AIL" mode is disabled which may slow interrupts
128+
and system calls on the host.
129+
121130
config KVM_BOOK3S_HV_EXIT_TIMING
122131
bool "Detailed timing for hypervisor real-mode code"
123132
depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS

arch/powerpc/kvm/book3s_hv.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
225225
int cpu;
226226
struct rcuwait *waitp;
227227

228+
/*
229+
* rcuwait_wake_up contains smp_mb() which orders prior stores that
230+
* create pending work vs below loads of cpu fields. The other side
231+
* is the barrier in vcpu run that orders setting the cpu fields vs
232+
* testing for pending work.
233+
*/
234+
228235
waitp = kvm_arch_vcpu_get_wait(vcpu);
229236
if (rcuwait_wake_up(waitp))
230237
++vcpu->stat.generic.halt_wakeup;
@@ -1089,7 +1096,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
10891096
break;
10901097
}
10911098
tvcpu->arch.prodded = 1;
1092-
smp_mb();
1099+
smp_mb(); /* This orders prodded store vs ceded load */
10931100
if (tvcpu->arch.ceded)
10941101
kvmppc_fast_vcpu_kick_hv(tvcpu);
10951102
break;
@@ -3766,6 +3773,14 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
37663773
pvc = core_info.vc[sub];
37673774
pvc->pcpu = pcpu + thr;
37683775
for_each_runnable_thread(i, vcpu, pvc) {
3776+
/*
3777+
* XXX: is kvmppc_start_thread called too late here?
3778+
* It updates vcpu->cpu and vcpu->arch.thread_cpu
3779+
* which are used by kvmppc_fast_vcpu_kick_hv(), but
3780+
* kick is called after new exceptions become available
3781+
* and exceptions are checked earlier than here, by
3782+
* kvmppc_core_prepare_to_enter.
3783+
*/
37693784
kvmppc_start_thread(vcpu, pvc);
37703785
kvmppc_create_dtl_entry(vcpu, pvc);
37713786
trace_kvm_guest_enter(vcpu);
@@ -4487,6 +4502,21 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
44874502
if (need_resched() || !kvm->arch.mmu_ready)
44884503
goto out;
44894504

4505+
vcpu->cpu = pcpu;
4506+
vcpu->arch.thread_cpu = pcpu;
4507+
vc->pcpu = pcpu;
4508+
local_paca->kvm_hstate.kvm_vcpu = vcpu;
4509+
local_paca->kvm_hstate.ptid = 0;
4510+
local_paca->kvm_hstate.fake_suspend = 0;
4511+
4512+
/*
4513+
* Orders set cpu/thread_cpu vs testing for pending interrupts and
4514+
* doorbells below. The other side is when these fields are set vs
4515+
* kvmppc_fast_vcpu_kick_hv reading the cpu/thread_cpu fields to
4516+
* kick a vCPU to notice the pending interrupt.
4517+
*/
4518+
smp_mb();
4519+
44904520
if (!nested) {
44914521
kvmppc_core_prepare_to_enter(vcpu);
44924522
if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
@@ -4506,13 +4536,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
45064536

45074537
tb = mftb();
45084538

4509-
vcpu->cpu = pcpu;
4510-
vcpu->arch.thread_cpu = pcpu;
4511-
vc->pcpu = pcpu;
4512-
local_paca->kvm_hstate.kvm_vcpu = vcpu;
4513-
local_paca->kvm_hstate.ptid = 0;
4514-
local_paca->kvm_hstate.fake_suspend = 0;
4515-
45164539
__kvmppc_create_dtl_entry(vcpu, pcpu, tb + vc->tb_offset, 0);
45174540

45184541
trace_kvm_guest_enter(vcpu);
@@ -4614,6 +4637,8 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
46144637
run->exit_reason = KVM_EXIT_INTR;
46154638
vcpu->arch.ret = -EINTR;
46164639
out:
4640+
vcpu->cpu = -1;
4641+
vcpu->arch.thread_cpu = -1;
46174642
powerpc_local_irq_pmu_restore(flags);
46184643
preempt_enable();
46194644
goto done;

arch/powerpc/kvm/book3s_pr.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,15 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu)
137137
svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max;
138138
svcpu->in_use = 0;
139139
svcpu_put(svcpu);
140-
#endif
141140

142141
/* Disable AIL if supported */
143-
if (cpu_has_feature(CPU_FTR_HVMODE) &&
144-
cpu_has_feature(CPU_FTR_ARCH_207S))
145-
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
142+
if (cpu_has_feature(CPU_FTR_HVMODE)) {
143+
if (cpu_has_feature(CPU_FTR_ARCH_207S))
144+
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
145+
if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
146+
mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) & ~FSCR_SCV);
147+
}
148+
#endif
146149

147150
vcpu->cpu = smp_processor_id();
148151
#ifdef CONFIG_PPC_BOOK3S_32
@@ -165,6 +168,14 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
165168
memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb));
166169
to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max;
167170
svcpu_put(svcpu);
171+
172+
/* Enable AIL if supported */
173+
if (cpu_has_feature(CPU_FTR_HVMODE)) {
174+
if (cpu_has_feature(CPU_FTR_ARCH_207S))
175+
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
176+
if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
177+
mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) | FSCR_SCV);
178+
}
168179
#endif
169180

170181
if (kvmppc_is_split_real(vcpu))
@@ -174,11 +185,6 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
174185
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
175186
kvmppc_save_tm_pr(vcpu);
176187

177-
/* Enable AIL if supported */
178-
if (cpu_has_feature(CPU_FTR_HVMODE) &&
179-
cpu_has_feature(CPU_FTR_ARCH_207S))
180-
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
181-
182188
vcpu->cpu = -1;
183189
}
184190

@@ -1037,6 +1043,8 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
10371043

10381044
void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
10391045
{
1046+
if (fscr & FSCR_SCV)
1047+
fscr &= ~FSCR_SCV; /* SCV must not be enabled */
10401048
if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) {
10411049
/* TAR got dropped, drop it in shadow too */
10421050
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);

arch/powerpc/kvm/book3s_pr_papr.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
281281
return EMULATE_DONE;
282282
}
283283

284+
static int kvmppc_h_pr_set_mode(struct kvm_vcpu *vcpu)
285+
{
286+
unsigned long mflags = kvmppc_get_gpr(vcpu, 4);
287+
unsigned long resource = kvmppc_get_gpr(vcpu, 5);
288+
289+
if (resource == H_SET_MODE_RESOURCE_ADDR_TRANS_MODE) {
290+
/* KVM PR does not provide AIL!=0 to guests */
291+
if (mflags == 0)
292+
kvmppc_set_gpr(vcpu, 3, H_SUCCESS);
293+
else
294+
kvmppc_set_gpr(vcpu, 3, H_UNSUPPORTED_FLAG_START - 63);
295+
return EMULATE_DONE;
296+
}
297+
return EMULATE_FAIL;
298+
}
299+
284300
#ifdef CONFIG_SPAPR_TCE_IOMMU
285301
static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
286302
{
@@ -384,6 +400,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
384400
return kvmppc_h_pr_logical_ci_load(vcpu);
385401
case H_LOGICAL_CI_STORE:
386402
return kvmppc_h_pr_logical_ci_store(vcpu);
403+
case H_SET_MODE:
404+
return kvmppc_h_pr_set_mode(vcpu);
387405
case H_XIRR:
388406
case H_CPPR:
389407
case H_EOI:
@@ -421,6 +439,7 @@ int kvmppc_hcall_impl_pr(unsigned long cmd)
421439
case H_CEDE:
422440
case H_LOGICAL_CI_LOAD:
423441
case H_LOGICAL_CI_STORE:
442+
case H_SET_MODE:
424443
#ifdef CONFIG_KVM_XICS
425444
case H_XIRR:
426445
case H_CPPR:
@@ -447,6 +466,7 @@ static unsigned int default_hcall_list[] = {
447466
H_BULK_REMOVE,
448467
H_PUT_TCE,
449468
H_CEDE,
469+
H_SET_MODE,
450470
#ifdef CONFIG_KVM_XICS
451471
H_XIRR,
452472
H_CPPR,

arch/powerpc/kvm/powerpc.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,23 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
705705
r = 1;
706706
break;
707707
#endif
708+
case KVM_CAP_PPC_AIL_MODE_3:
709+
r = 0;
710+
/*
711+
* KVM PR, POWER7, and some POWER9s don't support AIL=3 mode.
712+
* The POWER9s can support it if the guest runs in hash mode,
713+
* but QEMU doesn't necessarily query the capability in time.
714+
*/
715+
if (hv_enabled) {
716+
if (kvmhv_on_pseries()) {
717+
if (pseries_reloc_on_exception())
718+
r = 1;
719+
} else if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
720+
!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
721+
r = 1;
722+
}
723+
}
724+
break;
708725
default:
709726
r = 0;
710727
break;

arch/powerpc/platforms/pseries/setup.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ static void pseries_lpar_idle(void)
353353
pseries_idle_epilog();
354354
}
355355

356+
static bool pseries_reloc_on_exception_enabled;
357+
358+
bool pseries_reloc_on_exception(void)
359+
{
360+
return pseries_reloc_on_exception_enabled;
361+
}
362+
EXPORT_SYMBOL_GPL(pseries_reloc_on_exception);
363+
356364
/*
357365
* Enable relocation on during exceptions. This has partition wide scope and
358366
* may take a while to complete, if it takes longer than one second we will
@@ -377,6 +385,7 @@ bool pseries_enable_reloc_on_exc(void)
377385
" on exceptions: %ld\n", rc);
378386
return false;
379387
}
388+
pseries_reloc_on_exception_enabled = true;
380389
return true;
381390
}
382391

@@ -404,7 +413,9 @@ void pseries_disable_reloc_on_exc(void)
404413
break;
405414
mdelay(get_longbusy_msecs(rc));
406415
}
407-
if (rc != H_SUCCESS)
416+
if (rc == H_SUCCESS)
417+
pseries_reloc_on_exception_enabled = false;
418+
else
408419
pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
409420
rc);
410421
}

0 commit comments

Comments
 (0)