mptsas: bring back deprecated PCI ids #CFHack #CFHack2024 megaraid_sas: bring back deprecated PCI ids #CFHack #CFHack2024 qla2xxx: bring back deprecated PCI ids #CFHack #CFHack2024 qla4xxx: bring back deprecated PCI ids lpfc: bring back deprecated PCI ids be2iscsi: bring back deprecated PCI ids kernel/rh_messages.h: enable all disabled pci devices by moving to unmaintained Use AlmaLinux OS secure boot cert Debrand for AlmaLinux OS Add KVM support for ppc64le
311 lines
12 KiB
Diff
311 lines
12 KiB
Diff
From 3c806e795bf954e4dc28b75887a89095815325ed Mon Sep 17 00:00:00 2001
|
|
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
|
Date: Sat, 17 May 2025 08:48:11 +0000
|
|
Subject: [PATCH] =?UTF-8?q?Bring=20back=20KVM=20support=20for=20PPC=C2=A7?=
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Backport of the following upstream commits:
|
|
524ab50336b1190547ceb8074260a1fbebfee0be
|
|
93b71801a8274cd9511557faf04365a5de487197
|
|
f771b55731fc82b1e8e9ef123f6f1b8d8c92bc63
|
|
---
|
|
Documentation/virt/kvm/api.rst | 14 ++++++++++++++
|
|
arch/powerpc/include/asm/kvm_ppc.h | 4 ----
|
|
arch/powerpc/include/asm/setup.h | 2 ++
|
|
arch/powerpc/kvm/book3s.c | 6 ++----
|
|
arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +-
|
|
arch/powerpc/kvm/book3s_hv.c | 12 +++---------
|
|
arch/powerpc/kvm/book3s_pr.c | 2 --
|
|
arch/powerpc/kvm/booke.c | 2 --
|
|
arch/powerpc/kvm/powerpc.c | 21 +++++++++++++++++++--
|
|
arch/powerpc/platforms/pseries/setup.c | 13 ++++++++++++-
|
|
10 files changed, 53 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
|
|
index 9f2f130c6..64aca1034 100644
|
|
--- a/Documentation/virt/kvm/api.rst
|
|
+++ b/Documentation/virt/kvm/api.rst
|
|
@@ -7735,6 +7735,20 @@ indicated by the fd to the VM this is called on.
|
|
This is intended to support intra-host migration of VMs between userspace VMMs,
|
|
upgrading the VMM process without interrupting the guest.
|
|
|
|
+7.30 KVM_CAP_PPC_AIL_MODE_3
|
|
+-------------------------------
|
|
+
|
|
+:Capability: KVM_CAP_PPC_AIL_MODE_3
|
|
+:Architectures: ppc
|
|
+:Type: vm
|
|
+
|
|
+This capability indicates that the kernel supports the mode 3 setting for the
|
|
+"Address Translation Mode on Interrupt" aka "Alternate Interrupt Location"
|
|
+resource that is controlled with the H_SET_MODE hypercall.
|
|
+
|
|
+This capability allows a guest kernel to use a better-performance mode for
|
|
+handling interrupts and system calls.
|
|
+
|
|
7.31 KVM_CAP_DISABLE_QUIRKS2
|
|
----------------------------
|
|
|
|
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
|
|
index 254a41648..e16491011 100644
|
|
--- a/arch/powerpc/include/asm/kvm_ppc.h
|
|
+++ b/arch/powerpc/include/asm/kvm_ppc.h
|
|
@@ -199,12 +199,10 @@ extern void kvmppc_core_destroy_vm(struct kvm *kvm);
|
|
extern void kvmppc_core_free_memslot(struct kvm *kvm,
|
|
struct kvm_memory_slot *slot);
|
|
extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change);
|
|
extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change);
|
|
@@ -274,12 +272,10 @@ struct kvmppc_ops {
|
|
int (*get_dirty_log)(struct kvm *kvm, struct kvm_dirty_log *log);
|
|
void (*flush_memslot)(struct kvm *kvm, struct kvm_memory_slot *memslot);
|
|
int (*prepare_memory_region)(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change);
|
|
void (*commit_memory_region)(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change);
|
|
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
|
|
index 31f315223..1868e4a07 100644
|
|
--- a/arch/powerpc/include/asm/setup.h
|
|
+++ b/arch/powerpc/include/asm/setup.h
|
|
@@ -27,11 +27,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);
|
|
extern void 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) {}
|
|
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
|
|
index 64fd4b3ea..cb7b5f365 100644
|
|
--- a/arch/powerpc/kvm/book3s.c
|
|
+++ b/arch/powerpc/kvm/book3s.c
|
|
@@ -847,21 +847,19 @@ void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot)
|
|
}
|
|
|
|
int kvmppc_core_prepare_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- return kvm->arch.kvm_ops->prepare_memory_region(kvm, mem, old, new, change);
|
|
+ return kvm->arch.kvm_ops->prepare_memory_region(kvm, old, new, change);
|
|
}
|
|
|
|
void kvmppc_core_commit_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change);
|
|
+ kvm->arch.kvm_ops->commit_memory_region(kvm, old, new, change);
|
|
}
|
|
|
|
bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
|
|
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
|
|
index f38dfe195..16e5872a1 100644
|
|
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
|
|
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
|
|
@@ -488,7 +488,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
|
|
/*
|
|
* used to check for invalidations in progress
|
|
*/
|
|
- mmu_seq = kvm->mmu_notifier_seq;
|
|
+ mmu_seq = kvm->mmu_invalidate_seq;
|
|
smp_rmb();
|
|
|
|
stt = kvmppc_find_table(vcpu->kvm, liobn);
|
|
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
|
|
index 5b2530818..f6ce07b4b 100644
|
|
--- a/arch/powerpc/kvm/book3s_hv.c
|
|
+++ b/arch/powerpc/kvm/book3s_hv.c
|
|
@@ -4777,15 +4777,12 @@ static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *slot)
|
|
}
|
|
|
|
static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- unsigned long npages = mem->memory_size >> PAGE_SHIFT;
|
|
-
|
|
if (change == KVM_MR_CREATE) {
|
|
- new->arch.rmap = vzalloc(array_size(npages,
|
|
+ new->arch.rmap = vzalloc(array_size(new->npages,
|
|
sizeof(*new->arch.rmap)));
|
|
if (!new->arch.rmap)
|
|
return -ENOMEM;
|
|
@@ -4797,20 +4794,17 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
|
|
}
|
|
|
|
static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- unsigned long npages = mem->memory_size >> PAGE_SHIFT;
|
|
-
|
|
/*
|
|
- * If we are making a new memslot, it might make
|
|
+ * If we are creating or modifying a memslot, it might make
|
|
* some address that was previously cached as emulated
|
|
* MMIO be no longer emulated MMIO, so invalidate
|
|
* all the caches of emulated MMIO translations.
|
|
*/
|
|
- if (npages)
|
|
+ if (change != KVM_MR_DELETE)
|
|
atomic64_inc(&kvm->arch.mmio_update);
|
|
|
|
/*
|
|
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
|
|
index 48b48311a..6884c04f2 100644
|
|
--- a/arch/powerpc/kvm/book3s_pr.c
|
|
+++ b/arch/powerpc/kvm/book3s_pr.c
|
|
@@ -1892,7 +1892,6 @@ static void kvmppc_core_flush_memslot_pr(struct kvm *kvm,
|
|
}
|
|
|
|
static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
@@ -1901,7 +1900,6 @@ static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm,
|
|
}
|
|
|
|
static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
|
|
index b06ca6646..6cf2db284 100644
|
|
--- a/arch/powerpc/kvm/booke.c
|
|
+++ b/arch/powerpc/kvm/booke.c
|
|
@@ -1806,7 +1806,6 @@ void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot)
|
|
}
|
|
|
|
int kvmppc_core_prepare_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
const struct kvm_memory_slot *old,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
@@ -1815,7 +1814,6 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm,
|
|
}
|
|
|
|
void kvmppc_core_commit_memory_region(struct kvm *kvm,
|
|
- const struct kvm_userspace_memory_region *mem,
|
|
struct kvm_memory_slot *old,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
|
|
index 818815e15..b89271923 100644
|
|
--- a/arch/powerpc/kvm/powerpc.c
|
|
+++ b/arch/powerpc/kvm/powerpc.c
|
|
@@ -662,6 +662,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;
|
|
@@ -686,7 +703,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|
struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- return kvmppc_core_prepare_memory_region(kvm, mem, old, new, change);
|
|
+ return kvmppc_core_prepare_memory_region(kvm, old, new, change);
|
|
}
|
|
|
|
void kvm_arch_commit_memory_region(struct kvm *kvm,
|
|
@@ -694,7 +711,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
|
|
const struct kvm_memory_slot *new,
|
|
enum kvm_mr_change change)
|
|
{
|
|
- kvmppc_core_commit_memory_region(kvm, mem, old, new, change);
|
|
+ kvmppc_core_commit_memory_region(kvm, old, new, change);
|
|
}
|
|
|
|
void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
|
|
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
|
|
index f5c2718e2..1f7e535ab 100644
|
|
--- a/arch/powerpc/platforms/pseries/setup.c
|
|
+++ b/arch/powerpc/platforms/pseries/setup.c
|
|
@@ -367,6 +367,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
|
|
@@ -391,6 +399,7 @@ bool pseries_enable_reloc_on_exc(void)
|
|
" on exceptions: %ld\n", rc);
|
|
return false;
|
|
}
|
|
+ pseries_reloc_on_exception_enabled = true;
|
|
return true;
|
|
}
|
|
|
|
@@ -418,7 +427,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);
|
|
}
|
|
--
|
|
2.43.5
|
|
|