227 lines
8.6 KiB
Diff
227 lines
8.6 KiB
Diff
|
|
From 0ec1c95eea8c68243919ee4f8cd28b9a97dfc2f0 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Date: Mon, 15 Apr 2024 22:37:53 +0800
|
||
|
|
Subject: [PATCH] arm/virt: Use separate filed to identify cpu-hotplug enable
|
||
|
|
|
||
|
|
The mc->has_hotpluggable_cpus should not be modified after
|
||
|
|
machine class init.
|
||
|
|
|
||
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
---
|
||
|
|
accel/kvm/kvm-all.c | 6 ++++++
|
||
|
|
hw/arm/virt-acpi-build.c | 13 +++++--------
|
||
|
|
hw/arm/virt.c | 20 +++++++++++++-------
|
||
|
|
include/hw/arm/virt.h | 1 +
|
||
|
|
include/sysemu/kvm.h | 2 ++
|
||
|
|
include/sysemu/kvm_int.h | 1 +
|
||
|
|
target/arm/kvm.c | 7 +++----
|
||
|
|
7 files changed, 31 insertions(+), 19 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||
|
|
index 75a3075c14..b791aad1d6 100644
|
||
|
|
--- a/accel/kvm/kvm-all.c
|
||
|
|
+++ b/accel/kvm/kvm-all.c
|
||
|
|
@@ -3603,6 +3603,11 @@ bool kvm_kernel_irqchip_split(void)
|
||
|
|
return kvm_state->kernel_irqchip_split == ON_OFF_AUTO_ON;
|
||
|
|
}
|
||
|
|
|
||
|
|
+bool kvm_smccc_filter_enabled(void)
|
||
|
|
+{
|
||
|
|
+ return kvm_state->kvm_smccc_filter_enabled;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static void kvm_get_dirty_ring_size(Object *obj, Visitor *v,
|
||
|
|
const char *name, void *opaque,
|
||
|
|
Error **errp)
|
||
|
|
@@ -3648,6 +3653,7 @@ static void kvm_accel_instance_init(Object *obj)
|
||
|
|
/* KVM dirty ring is by default off */
|
||
|
|
s->kvm_dirty_ring_size = 0;
|
||
|
|
s->kvm_dirty_ring_with_bitmap = false;
|
||
|
|
+ s->kvm_smccc_filter_enabled = false;
|
||
|
|
s->kvm_eager_split_size = 0;
|
||
|
|
s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN;
|
||
|
|
s->notify_window = 0;
|
||
|
|
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||
|
|
index 46642efac4..99296fc6d8 100644
|
||
|
|
--- a/hw/arm/virt-acpi-build.c
|
||
|
|
+++ b/hw/arm/virt-acpi-build.c
|
||
|
|
@@ -779,12 +779,10 @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size)
|
||
|
|
build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */
|
||
|
|
}
|
||
|
|
|
||
|
|
-static uint32_t virt_acpi_get_gicc_flags(CPUState *cpu)
|
||
|
|
+static uint32_t virt_acpi_get_gicc_flags(CPUState *cpu, VirtMachineState *vms)
|
||
|
|
{
|
||
|
|
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||
|
|
-
|
||
|
|
/* can only exist in 'enabled' state */
|
||
|
|
- if (!mc->has_hotpluggable_cpus) {
|
||
|
|
+ if (!vms->cpu_hotplug_enabled) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -842,7 +840,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||
|
|
uint64_t physical_base_address = 0, gich = 0, gicv = 0;
|
||
|
|
uint32_t vgic_interrupt = vms->virt ? ARCH_GIC_MAINT_IRQ : 0;
|
||
|
|
uint32_t pmu_interrupt = vms->pmu ? VIRTUAL_PMU_IRQ : 0;
|
||
|
|
- uint32_t flags = virt_acpi_get_gicc_flags(cpu);
|
||
|
|
+ uint32_t flags = virt_acpi_get_gicc_flags(cpu, vms);
|
||
|
|
uint64_t mpidr = qemu_get_cpu_archid(i);
|
||
|
|
|
||
|
|
if (vms->gic_version == VIRT_GIC_VERSION_2) {
|
||
|
|
@@ -1003,7 +1001,6 @@ static void
|
||
|
|
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||
|
|
{
|
||
|
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||
|
|
- MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||
|
|
Aml *scope, *dsdt;
|
||
|
|
MachineState *ms = MACHINE(vms);
|
||
|
|
const MemMapEntry *memmap = vms->memmap;
|
||
|
|
@@ -1020,8 +1017,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||
|
|
* the RTC ACPI device at all when using UEFI.
|
||
|
|
*/
|
||
|
|
scope = aml_scope("\\_SB");
|
||
|
|
- /* if GED is enabled then cpus AML shall be added as part build_cpus_aml */
|
||
|
|
- if (mc->has_hotpluggable_cpus) {
|
||
|
|
+
|
||
|
|
+ if (vms->cpu_hotplug_enabled) {
|
||
|
|
CPUHotplugFeatures opts = {
|
||
|
|
.acpi_1_compatible = false,
|
||
|
|
.has_legacy_cphp = false
|
||
|
|
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||
|
|
index 73b29c7f73..44931355d6 100644
|
||
|
|
--- a/hw/arm/virt.c
|
||
|
|
+++ b/hw/arm/virt.c
|
||
|
|
@@ -756,7 +756,7 @@ static void virt_add_gic_cpuhp_notifier(VirtMachineState *vms)
|
||
|
|
{
|
||
|
|
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||
|
|
|
||
|
|
- if (mc->has_hotpluggable_cpus) {
|
||
|
|
+ if (mc->has_hotpluggable_cpus && vms->gic_version >= VIRT_GIC_VERSION_3) {
|
||
|
|
Notifier *cpuhp_notifier = gicv3_cpuhp_notifier(vms->gic);
|
||
|
|
notifier_list_add(&vms->cpuhp_notifiers, cpuhp_notifier);
|
||
|
|
}
|
||
|
|
@@ -2498,11 +2498,16 @@ static void machvirt_init(MachineState *machine)
|
||
|
|
has_ged = has_ged && firmware_loaded &&
|
||
|
|
virt_is_acpi_enabled(vms) &&
|
||
|
|
!!object_class_dynamic_cast(cpu_class, TYPE_AARCH64_CPU);
|
||
|
|
+
|
||
|
|
if (tcg_enabled() || hvf_enabled() || qtest_enabled() ||
|
||
|
|
+ (kvm_enabled() && !kvm_smccc_filter_enabled()) ||
|
||
|
|
(vms->gic_version < VIRT_GIC_VERSION_3) || !has_ged) {
|
||
|
|
- mc->has_hotpluggable_cpus = false;
|
||
|
|
+ vms->cpu_hotplug_enabled = false;
|
||
|
|
+ } else {
|
||
|
|
+ vms->cpu_hotplug_enabled = true;
|
||
|
|
}
|
||
|
|
- if (!mc->has_hotpluggable_cpus) {
|
||
|
|
+
|
||
|
|
+ if (!vms->cpu_hotplug_enabled) {
|
||
|
|
if (machine->smp.max_cpus > smp_cpus) {
|
||
|
|
warn_report("cpu hotplug feature has been disabled");
|
||
|
|
}
|
||
|
|
@@ -3174,7 +3179,6 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||
|
|
{
|
||
|
|
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||
|
|
MachineState *ms = MACHINE(hotplug_dev);
|
||
|
|
- MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||
|
|
ARMCPU *cpu = ARM_CPU(dev);
|
||
|
|
CPUState *cs = CPU(dev);
|
||
|
|
CPUArchId *cpu_slot;
|
||
|
|
@@ -3218,7 +3222,7 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (cs->cpu_index >= ms->smp.cpus && !mc->has_hotpluggable_cpus) {
|
||
|
|
+ if (cs->cpu_index >= ms->smp.cpus && !vms->cpu_hotplug_enabled) {
|
||
|
|
error_setg(errp, "CPU [cold|hot]plug not supported on this machine");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
@@ -3304,7 +3308,6 @@ fail:
|
||
|
|
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
|
||
|
|
DeviceState *dev, Error **errp)
|
||
|
|
{
|
||
|
|
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||
|
|
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||
|
|
HotplugHandlerClass *hhc;
|
||
|
|
ARMCPU *cpu = ARM_CPU(dev);
|
||
|
|
@@ -3316,7 +3319,7 @@ static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (!mc->has_hotpluggable_cpus) {
|
||
|
|
+ if (!vms->cpu_hotplug_enabled) {
|
||
|
|
error_setg(errp, "CPU hot(un)plug not supported on this machine");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
@@ -3780,6 +3783,9 @@ static void virt_instance_init(Object *obj)
|
||
|
|
/* EL2 is also disabled by default, for similar reasons */
|
||
|
|
vms->virt = false;
|
||
|
|
|
||
|
|
+ /* CPU hotplug is enabled by default */
|
||
|
|
+ vms->cpu_hotplug_enabled = true;
|
||
|
|
+
|
||
|
|
/* High memory is enabled by default */
|
||
|
|
vms->highmem = true;
|
||
|
|
vms->highmem_compact = !vmc->no_highmem_compact;
|
||
|
|
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||
|
|
index ae0f5beb26..138531f9c1 100644
|
||
|
|
--- a/include/hw/arm/virt.h
|
||
|
|
+++ b/include/hw/arm/virt.h
|
||
|
|
@@ -153,6 +153,7 @@ struct VirtMachineState {
|
||
|
|
bool its;
|
||
|
|
bool tcg_its;
|
||
|
|
bool virt;
|
||
|
|
+ bool cpu_hotplug_enabled;
|
||
|
|
bool ras;
|
||
|
|
bool mte;
|
||
|
|
bool dtb_randomness;
|
||
|
|
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
|
||
|
|
index e534411ddc..cfa77cc15b 100644
|
||
|
|
--- a/include/sysemu/kvm.h
|
||
|
|
+++ b/include/sysemu/kvm.h
|
||
|
|
@@ -492,6 +492,8 @@ bool kvm_kernel_irqchip_allowed(void);
|
||
|
|
bool kvm_kernel_irqchip_required(void);
|
||
|
|
bool kvm_kernel_irqchip_split(void);
|
||
|
|
|
||
|
|
+bool kvm_smccc_filter_enabled(void);
|
||
|
|
+
|
||
|
|
/**
|
||
|
|
* kvm_arch_irqchip_create:
|
||
|
|
* @KVMState: The KVMState pointer
|
||
|
|
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
|
||
|
|
index fd846394be..b2d2c59477 100644
|
||
|
|
--- a/include/sysemu/kvm_int.h
|
||
|
|
+++ b/include/sysemu/kvm_int.h
|
||
|
|
@@ -112,6 +112,7 @@ struct KVMState
|
||
|
|
uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */
|
||
|
|
uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */
|
||
|
|
bool kvm_dirty_ring_with_bitmap;
|
||
|
|
+ bool kvm_smccc_filter_enabled;
|
||
|
|
uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
|
||
|
|
struct KVMDirtyRingReaper reaper;
|
||
|
|
NotifyVmexitOption notify_vmexit;
|
||
|
|
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
|
||
|
|
index 19783d567f..12c1b4b328 100644
|
||
|
|
--- a/target/arm/kvm.c
|
||
|
|
+++ b/target/arm/kvm.c
|
||
|
|
@@ -321,12 +321,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||
|
|
if (kvm_arm_set_smccc_filter(PSCI_0_2_FN64_CPU_ON,
|
||
|
|
KVM_SMCCC_FILTER_FWD_TO_USER)) {
|
||
|
|
error_report("CPU On PSCI-to-user-space fwd filter install failed");
|
||
|
|
- mc->has_hotpluggable_cpus = false;
|
||
|
|
- }
|
||
|
|
- if (kvm_arm_set_smccc_filter(PSCI_0_2_FN_CPU_OFF,
|
||
|
|
+ } else if (kvm_arm_set_smccc_filter(PSCI_0_2_FN_CPU_OFF,
|
||
|
|
KVM_SMCCC_FILTER_FWD_TO_USER)) {
|
||
|
|
error_report("CPU Off PSCI-to-user-space fwd filter install failed");
|
||
|
|
- mc->has_hotpluggable_cpus = false;
|
||
|
|
+ } else {
|
||
|
|
+ s->kvm_smccc_filter_enabled = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
--
|
||
|
|
2.41.0
|
||
|
|
|