KVM: PPC: Use KVM_CAP_PPC_AIL_MODE_3

Use KVM_CAP_PPC_AIL_MODE_3 to advertise the capability to set the AIL
resource mode to 3 with the H_SET_MODE hypercall. This capability
differs between processor types and KVM types (PR, HV, Nested HV), and
affects guest-visible behaviour.

QEMU will implement a cap-ail-mode-3 to control this behaviour[1], and
use the KVM CAP if available to determine KVM support[2].

[1] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00437.html
[2] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00439.html

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
[mpe: Rebase onto 93b71801a8 from kvm-ppc-cap-210 branch, add EXPORT_SYMBOL]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220222064727.2314380-4-npiggin@gmail.com
This commit is contained in:
Nicholas Piggin 2022-03-07 13:26:25 +11:00 committed by Michael Ellerman
parent 839d893b40
commit f771b55731
3 changed files with 31 additions and 1 deletions

View File

@ -28,11 +28,13 @@ void setup_panic(void);
#define ARCH_PANIC_TIMEOUT 180
#ifdef CONFIG_PPC_PSERIES
extern bool pseries_reloc_on_exception(void);
extern bool pseries_enable_reloc_on_exc(void);
extern void pseries_disable_reloc_on_exc(void);
extern void pseries_big_endian_exceptions(void);
void __init pseries_little_endian_exceptions(void);
#else
static inline bool pseries_reloc_on_exception(void) { return false; }
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
static inline void pseries_disable_reloc_on_exc(void) {}
static inline void pseries_big_endian_exceptions(void) {}

View File

@ -705,6 +705,23 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
#endif
case KVM_CAP_PPC_AIL_MODE_3:
r = 0;
/*
* KVM PR, POWER7, and some POWER9s don't support AIL=3 mode.
* The POWER9s can support it if the guest runs in hash mode,
* but QEMU doesn't necessarily query the capability in time.
*/
if (hv_enabled) {
if (kvmhv_on_pseries()) {
if (pseries_reloc_on_exception())
r = 1;
} else if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
r = 1;
}
}
break;
default:
r = 0;
break;

View File

@ -353,6 +353,14 @@ static void pseries_lpar_idle(void)
pseries_idle_epilog();
}
static bool pseries_reloc_on_exception_enabled;
bool pseries_reloc_on_exception(void)
{
return pseries_reloc_on_exception_enabled;
}
EXPORT_SYMBOL_GPL(pseries_reloc_on_exception);
/*
* Enable relocation on during exceptions. This has partition wide scope and
* 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)
" on exceptions: %ld\n", rc);
return false;
}
pseries_reloc_on_exception_enabled = true;
return true;
}
@ -404,7 +413,9 @@ void pseries_disable_reloc_on_exc(void)
break;
mdelay(get_longbusy_msecs(rc));
}
if (rc != H_SUCCESS)
if (rc == H_SUCCESS)
pseries_reloc_on_exception_enabled = false;
else
pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
rc);
}