diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2023-05-16 02:02:16 +1000 |
---|---|---|
committer | Daniel Henrique Barboza <danielhb413@gmail.com> | 2023-05-28 07:13:54 -0300 |
commit | ccc5a4c5e108775667ffc25182cd2ba2326ac979 (patch) | |
tree | dfd3caaf7382d24d54fa94b1e561fa2b2d68d3e1 /target | |
parent | 4ee5d2817ff18d10be887853d5e966247f0a0c30 (diff) |
spapr: Add SPAPR_CAP_AIL_MODE_3 for AIL mode 3 support for H_SET_MODE hcall
The behaviour of the Address Translation Mode on Interrupt resource is
not consistently supported by all CPU versions or all KVM versions: KVM
HV does not support mode 2, and does not support mode 3 on POWER7 or
early POWER9 processesors. KVM PR only supports mode 0. TCG supports all
modes (0, 2, 3) on CPUs with support for the corresonding LPCR[AIL] mode.
This leads to inconsistencies in guest behaviour and could cause problems
migrating guests.
This was not noticable for Linux guests for a long time because the
kernel only uses modes 0 and 3, and it used to consider AIL-3 to be
advisory in that it would always keep the AIL-0 vectors around, so it
did not matter whether or not interrupts were delivered according to
the AIL mode. Recent Linux guests depend on AIL mode 3 working as
specified in order to support the SCV facility interrupt. If AIL-3 can
not be provided, then H_SET_MODE must return an error to Linux so it can
disable the SCV facility (failure to do so can lead to userspace being
able to crash the guest kernel).
Add the ail-mode-3 capability to specify that AIL-3 is supported. AIL-0
is implied as the baseline, and AIL-2 is no longer supported by spapr.
AIL-2 is not known to be used by any software, but support in TCG could
be restored with an ail-mode-2 capability quite easily if a regression
is reported.
Modify the H_SET_MODE Address Translation Mode on Interrupt resource
handler to check capabilities and correctly return error if not
supported.
KVM has a cap to advertise support for AIL-3.
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20230515160216.394612-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/kvm.c | 7 | ||||
-rw-r--r-- | target/ppc/kvm_ppc.h | 6 |
2 files changed, 13 insertions, 0 deletions
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 336e663bc3..a7f2de9d10 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -88,6 +88,7 @@ static int cap_ppc_nested_kvm_hv; static int cap_large_decr; static int cap_fwnmi; static int cap_rpt_invalidate; +static int cap_ail_mode_3; static uint32_t debug_inst_opcode; @@ -152,6 +153,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } cap_rpt_invalidate = kvm_vm_check_extension(s, KVM_CAP_PPC_RPT_INVALIDATE); + cap_ail_mode_3 = kvm_vm_check_extension(s, KVM_CAP_PPC_AIL_MODE_3); kvm_ppc_register_host_cpu_type(); return 0; @@ -2560,6 +2562,11 @@ int kvmppc_has_cap_rpt_invalidate(void) return cap_rpt_invalidate; } +bool kvmppc_supports_ail_3(void) +{ + return cap_ail_mode_3; +} + PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) { uint32_t host_pvr = mfpvr(); diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 5fd9753953..611debc3ce 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -76,6 +76,7 @@ int kvmppc_set_cap_nested_kvm_hv(int enable); int kvmppc_get_cap_large_decr(void); int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable); int kvmppc_has_cap_rpt_invalidate(void); +bool kvmppc_supports_ail_3(void); int kvmppc_enable_hwrng(void); int kvmppc_put_books_sregs(PowerPCCPU *cpu); PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); @@ -396,6 +397,11 @@ static inline int kvmppc_has_cap_rpt_invalidate(void) return false; } +static inline bool kvmppc_supports_ail_3(void) +{ + return false; +} + static inline int kvmppc_enable_hwrng(void) { return -1; |