[PATCH V13 7/8] gdbstub: Add helper function to unregister GDB register space

2024-06-07 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Note: These are common functions exported to arch specific code. For example,
for ARM this code is being referred in associated arch specific patch-set:

Link: 
https://lore.kernel.org/qemu-devel/20230926103654.34424-1-salil.me...@huawei.com/

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Tested-by: Zhao Liu 
---
 gdbstub/gdbstub.c  | 13 +
 hw/core/cpu-common.c   |  1 -
 include/exec/gdbstub.h |  6 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b3574997ea..1949b09240 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_regs = 0;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 0f0a247f56..e5140b4bc1 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)
 {
 CPUState *cpu = CPU(obj);
 
-g_array_free(cpu->gdb_regs, TRUE);
 qemu_lockcnt_destroy(>in_ioctl_lock);
 qemu_mutex_destroy(>work_mutex);
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V13 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-06-07 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d043..240ee04369 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..60b160d0b4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -486,6 +486,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 struct CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 342b7a8fd4..146f17826a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V13 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-06-07 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Zhao Liu 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V13 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-06-07 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index af2b6655d2..4c63514b16 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -343,9 +343,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -370,13 +371,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -700,9 +707,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..b73b136605 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1537,7 +1537,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, 

[PATCH V13 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-06-07 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 473b37ba88..af2b6655d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -327,7 +327,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 54d3b4bf9d..63226b0040 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V13 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-06-07 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Vishnu Pajjuri 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/cpu.c  |  6 +-
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..473b37ba88 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -221,7 +221,11 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 const CPUArchIdList *id_list;
 int i;
 
-assert(mc->possible_cpu_arch_ids);
+/* hotplug might not be available for all types like x86/microvm etc. */
+if (!mc->possible_cpu_arch_ids) {
+return;
+}
+
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..54d3b4bf9d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+  

[PATCH V13 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-06-07 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Reviewed-by: Nicholas Piggin 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
Reviewed-by: Harsh Prateek Bora 
---
 accel/kvm/kvm-all.c| 95 --
 accel/kvm/kvm-cpus.h   |  1 -
 accel/kvm/trace-events |  5 ++-
 include/sysemu/kvm.h   | 25 +++
 4 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..8f9128bb92 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -340,14 +340,71 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+int kvm_fd = -ENOENT;
+
+QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+}
+}
+
+trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "not found 
parked");
+
+return kvm_fd;
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +430,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -389,24 +443,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
-{
-struct KVMParkedVcpu *cpu;
-
-QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
-if (cpu->vcpu_id == vcpu_id) {
-int kvm_fd;
-
-QLIST_REMOVE(cpu, node);
-kvm_fd = cpu->kvm_fd;
-g_free(cpu);
-return kvm_fd;
-}
-}
-
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
 {
 KVMState *s = kvm_state;
@@ -415,19 +451,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index ca40add32c..171b22fd29 100644
--- a/accel/kvm/kvm-cpus.h

[PATCH V13 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-06-07 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V13 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-06-07 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v13

NOTE: This series is meant to work in conjunction with Architecture specific 
patch-set.
For ARM, a combined patch-set (arch agnostic + specific) was earlier pushed as 
RFC V2[1].
A ARM architecture specific patch-set (subset of RFC V2) is being finalized and 
shall
be floated soon as RFC-V3. Please find a version of it compatible with this 
patch-set at
the below location. (TCG support is broken in below and is being fixed)

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc2


Revision History:

Patch-set  V12 -> V13
1. Added Reviewed-by Tag of Harsh Prateek Bora's (IBM) [PATCH V12 1/8]
2. Moved the kvm_{create,park,unpark}_vcpu prototypes from accel/kvm/kvm-cpus.h
   to include/sysemu/kvm.h. These can later be exported through AccelOps.
Link: 
https://lore.kernel.org/qemu-devel/62f55169-1796-4d8e-a35d-7f003a172...@linux.ibm.com/

Patch-set  V11 -> V12
1. Addressed Harsh Prateek Bora's (IBM) comment
   - Changed @cpu to @vcpu_id in the kvm_unpark_vcpu protoype header/
2. Added Zhao Liu's (Intel) Tested-by for whole series
   - Qtest does not breaks on Intel platforms now.
3. Added Zhao Liu's (Intel) Reviewed-by for [PATCH V11 {1/8 - 3/8}]
Link: https://lore.kernel.org/qemu-devel/zlrspujgbgyeu...@intel.com/
Link: 
https://lore.kernel.org/qemu-devel/a5f3d78e-cfed-441f-9c56-e3e78fa5e...@linux.ibm.com/

Patch-set  V10 -> V11
1. Addressed Nicholas Piggin's (IBM) comment
   - moved the traces in kvm_unpark_vcpu and kvm_create_vcpu at the end
   - Added the Reviewed-by Tag for [PATCH V10 1/8]
2.  Addressed Alex Bennée's (Linaro) comments
   - Added a note explaining dependency of the [PATCH V10 7/8] on Arch specific 
patch-set
Link: https://lore.kernel.org/qemu-devel/d1fs5goofwwk.2pnrivl0v6...@gmail.com/ 
Link: https://lore.kernel.org/qemu-devel/87frubi402@draig.linaro.org/

Patch-set  V9 -> V10
1. Addressed Nicholas Piggin's (IBM) & Philippe Mathieu-Daudé (Linaro) comments
   - carved out kvm_unpark_vcpu and added its trace
   - Widened the scope of the kvm_unpark_vcpu so that it can be used by generic 
framework
 being thought out
Link: 
https://lore.kernel.org/qemu-devel/20240519210620.228342-1-salil.me...@huawei.com/
Link: 
https://lore.kernel.org/qemu-devel/e94b0e14-efee-4050-9c9f-08382a36b...@linaro.org/

Patch-set  V8 -> V9
1. Addressed Vishnu Pajjuri's (Ampere) comments
   - Added kvm_fd to trace in kvm_create_vcpu
   - Some clean ups: arch vcpu-id and sbd variable
   - Added the missed initialization of cpu->gdb_num_regs
2. Addressed the commnet from Zhao Liu (Intel)
   - Make initialization of CPU Hotplug state conditional 
(possible_cpu_arch_ids!=NULL)
Link: 
https://lore.kernel.org/qemu-devel/2024031202.12992-1-salil.me...@huawei.com/

Patch-set V7 -> V8
1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's 

[PATCH V12 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-05-29 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Zhao Liu 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V12 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-29 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Note: These are common functions exported to arch specific code. For example,
for ARM this code is being referred in associated arch specific patch-set:

Link: 
https://lore.kernel.org/qemu-devel/20230926103654.34424-1-salil.me...@huawei.com/

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Tested-by: Zhao Liu 
---
 gdbstub/gdbstub.c  | 13 +
 hw/core/cpu-common.c   |  1 -
 include/exec/gdbstub.h |  6 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b3574997ea..1949b09240 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_regs = 0;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 0f0a247f56..e5140b4bc1 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)
 {
 CPUState *cpu = CPU(obj);
 
-g_array_free(cpu->gdb_regs, TRUE);
 qemu_lockcnt_destroy(>in_ioctl_lock);
 qemu_mutex_destroy(>work_mutex);
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V12 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-29 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d043..240ee04369 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..60b160d0b4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -486,6 +486,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 struct CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 342b7a8fd4..146f17826a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V12 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-05-29 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index af2b6655d2..4c63514b16 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -343,9 +343,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -370,13 +371,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -700,9 +707,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..b73b136605 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1537,7 +1537,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, 

[PATCH V12 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-05-29 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Tested-by: Zhao Liu 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 473b37ba88..af2b6655d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -327,7 +327,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 54d3b4bf9d..63226b0040 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V12 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-29 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Vishnu Pajjuri 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/cpu.c  |  6 +-
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..473b37ba88 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -221,7 +221,11 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 const CPUArchIdList *id_list;
 int i;
 
-assert(mc->possible_cpu_arch_ids);
+/* hotplug might not be available for all types like x86/microvm etc. */
+if (!mc->possible_cpu_arch_ids) {
+return;
+}
+
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..54d3b4bf9d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+  

[PATCH V12 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-05-29 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V12 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-29 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Reviewed-by: Nicholas Piggin 
Tested-by: Zhao Liu 
Reviewed-by: Zhao Liu 
---
 accel/kvm/kvm-all.c| 95 --
 accel/kvm/kvm-cpus.h   | 23 ++
 accel/kvm/trace-events |  5 ++-
 3 files changed, 90 insertions(+), 33 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..8f9128bb92 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -340,14 +340,71 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+int kvm_fd = -ENOENT;
+
+QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+}
+}
+
+trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "not found 
parked");
+
+return kvm_fd;
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +430,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -389,24 +443,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
-{
-struct KVMParkedVcpu *cpu;
-
-QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
-if (cpu->vcpu_id == vcpu_id) {
-int kvm_fd;
-
-QLIST_REMOVE(cpu, node);
-kvm_fd = cpu->kvm_fd;
-g_free(cpu);
-return kvm_fd;
-}
-}
-
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
 {
 KVMState *s = kvm_state;
@@ -415,19 +451,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index ca40add32c..2c1cad4179 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -22,5 +22,28 @@ bool 

[PATCH V12 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-05-29 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v12

NOTE: This series is meant to work in conjunction with Architecture specific 
patch-set.
For ARM, this will work in combination of the architecture specific part based 
on
RFC V2 [1]. This architecture specific patch-set RFC V3 shall be floated soon 
and is
present at below location

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc1


Revision History:

Patch-set  V11 -> V12
1. Addressed Harsh Prateek Bora's (IBM) comment
   - Changed @cpu to @vcpu_id in the kvm_unpark_vcpu protoype header/
2. Added Zhao Liu's (Intel) Tested-by for whole series
   - Qtest does not breaks on Intel platforms now.
3. Added Zhao Liu's (Intel) Reviewed-by for [PATCH V11 {1/8 - 3/8}]
Link: https://lore.kernel.org/qemu-devel/zlrspujgbgyeu...@intel.com/
Link: 
https://lore.kernel.org/qemu-devel/a5f3d78e-cfed-441f-9c56-e3e78fa5e...@linux.ibm.com/

Patch-set  V10 -> V11
1. Addressed Nicholas Piggin's (IBM) comment
   - moved the traces in kvm_unpark_vcpu and kvm_create_vcpu at the end
   - Added the Reviewed-by Tag for [PATCH V10 1/8]
2.  Addressed Alex Bennée's (Linaro) comments
   - Added a note explaining dependency of the [PATCH V10 7/8] on Arch specific 
patch-set
Link: https://lore.kernel.org/qemu-devel/d1fs5goofwwk.2pnrivl0v6...@gmail.com/ 
Link: https://lore.kernel.org/qemu-devel/87frubi402@draig.linaro.org/

Patch-set  V9 -> V10
1. Addressed Nicholas Piggin's (IBM) & Philippe Mathieu-Daudé (Linaro) comments
   - carved out kvm_unpark_vcpu and added its trace
   - Widened the scope of the kvm_unpark_vcpu so that it can be used by generic 
framework
 being thought out
Link: 
https://lore.kernel.org/qemu-devel/20240519210620.228342-1-salil.me...@huawei.com/
Link: 
https://lore.kernel.org/qemu-devel/e94b0e14-efee-4050-9c9f-08382a36b...@linaro.org/

Patch-set  V8 -> V9
1. Addressed Vishnu Pajjuri's (Ampere) comments
   - Added kvm_fd to trace in kvm_create_vcpu
   - Some clean ups: arch vcpu-id and sbd variable
   - Added the missed initialization of cpu->gdb_num_regs
2. Addressed the commnet from Zhao Liu (Intel)
   - Make initialization of CPU Hotplug state conditional 
(possible_cpu_arch_ids!=NULL)
Link: 
https://lore.kernel.org/qemu-devel/2024031202.12992-1-salil.me...@huawei.com/

Patch-set V7 -> V8
1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed 

RE: [PATCH V11 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-23 Thread Salil Mehta via
>  From: Harsh Prateek Bora 
>  Sent: Thursday, May 23, 2024 8:05 AM
>  
>  Hi Salil,
>  
>  On 5/23/24 02:41, Salil Mehta wrote:
>  > +void kvm_park_vcpu(CPUState *cpu);
>  > +
>  > +/**
>  > + * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
>  > + * @s: KVM State
>  > + * @cpu: Architecture vCPU ID of the parked vCPU
>  
>  s/@cpu/@vcpuid ?


Thanks. Will fix this.

Cheers
Salil.


>  
>  Thanks
>  Harsh
>  > + *
>  > + * @returns: KVM fd
>  > + */
>  > +int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
>  >   #endif /* KVM_CPUS_H */


[PATCH V11 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-05-22 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V11 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-22 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Note: These are common functions exported to arch specific code. For example,
for ARM this code is being referred in associated arch specific patch-set:

Link: 
https://lore.kernel.org/qemu-devel/20230926103654.34424-1-salil.me...@huawei.com/

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
---
 gdbstub/gdbstub.c  | 13 +
 hw/core/cpu-common.c   |  1 -
 include/exec/gdbstub.h |  6 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b3574997ea..1949b09240 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_regs = 0;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 0f0a247f56..e5140b4bc1 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)
 {
 CPUState *cpu = CPU(obj);
 
-g_array_free(cpu->gdb_regs, TRUE);
 qemu_lockcnt_destroy(>in_ioctl_lock);
 qemu_mutex_destroy(>work_mutex);
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V11 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-22 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d043..240ee04369 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..60b160d0b4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -486,6 +486,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 struct CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 342b7a8fd4..146f17826a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V11 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-05-22 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 473b37ba88..af2b6655d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -327,7 +327,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 54d3b4bf9d..63226b0040 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V11 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-05-22 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index af2b6655d2..4c63514b16 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -343,9 +343,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -370,13 +371,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -700,9 +707,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..b73b136605 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1537,7 +1537,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 

[PATCH V11 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-22 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Vishnu Pajjuri 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/cpu.c  |  6 +-
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..473b37ba88 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -221,7 +221,11 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 const CPUArchIdList *id_list;
 int i;
 
-assert(mc->possible_cpu_arch_ids);
+/* hotplug might not be available for all types like x86/microvm etc. */
+if (!mc->possible_cpu_arch_ids) {
+return;
+}
+
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..54d3b4bf9d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } 

[PATCH V11 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-22 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
Reviewed-by: Nicholas Piggin 
---
 accel/kvm/kvm-all.c| 95 --
 accel/kvm/kvm-cpus.h   | 23 ++
 accel/kvm/trace-events |  5 ++-
 3 files changed, 90 insertions(+), 33 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..8f9128bb92 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -340,14 +340,71 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+int kvm_fd = -ENOENT;
+
+QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+}
+}
+
+trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "not found 
parked");
+
+return kvm_fd;
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +430,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -389,24 +443,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
-{
-struct KVMParkedVcpu *cpu;
-
-QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
-if (cpu->vcpu_id == vcpu_id) {
-int kvm_fd;
-
-QLIST_REMOVE(cpu, node);
-kvm_fd = cpu->kvm_fd;
-g_free(cpu);
-return kvm_fd;
-}
-}
-
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
 {
 KVMState *s = kvm_state;
@@ -415,19 +451,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index ca40add32c..2e6bb38b5d 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -22,5 +22,28 @@ bool kvm_supports_guest_debug(void);
 int 

[PATCH V11 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-05-22 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V11 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-05-22 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v10

NOTE: This series is meant to work in conjunction with Architecture specific 
patch-set.
For ARM, this will work in combination of the architecture specific part based 
on
RFC V2 [1]. This architecture specific patch-set RFC V3 shall be floated soon 
and is
present at below location

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc1


Revision History:

Patch-set  V10 -> V11
1. Addressed Nicholas Piggin's (IBM) comment
   - moved the traces in kvm_unpark_vcpu and kvm_create_vcpu at the end
   - Added the Reviewed-by Tag for [PATCH V10 1/8]
2.  Addressed Alex Bennée's (Linaro) comments
   - Added a note explaining dependency of the [PATCH V10 7/8] on Arch specific 
patch-set
Link: https://lore.kernel.org/qemu-devel/d1fs5goofwwk.2pnrivl0v6...@gmail.com/ 
Link: https://lore.kernel.org/qemu-devel/87frubi402@draig.linaro.org/

Patch-set  V9 -> V10
1. Addressed Nicholas Piggin's (IBM) & Philippe Mathieu-Daudé (Linaro) comments
   - carved out kvm_unpark_vcpu and added its trace
   - Widened the scope of the kvm_unpark_vcpu so that it can be used by generic 
framework
 being thought out
Link: 
https://lore.kernel.org/qemu-devel/20240519210620.228342-1-salil.me...@huawei.com/
Link: 
https://lore.kernel.org/qemu-devel/e94b0e14-efee-4050-9c9f-08382a36b...@linaro.org/

Patch-set  V8 -> V9
1. Addressed Vishnu Pajjuri's (Ampere) comments
   - Added kvm_fd to trace in kvm_create_vcpu
   - Some clean ups: arch vcpu-id and sbd variable
   - Added the missed initialization of cpu->gdb_num_regs
2. Addressed the commnet from Zhao Liu (Intel)
   - Make initialization of CPU Hotplug state conditional 
(possible_cpu_arch_ids!=NULL)
Link: 
https://lore.kernel.org/qemu-devel/2024031202.12992-1-salil.me...@huawei.com/

Patch-set V7 -> V8
1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/


RE: [PATCH V10 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-22 Thread Salil Mehta via
>  From: Nicholas Piggin 
>  Sent: Wednesday, May 22, 2024 2:25 AM
>  To: Salil Mehta ; qemu-devel@nongnu.org;
>  qemu-...@nongnu.org
>  
>  On Tue May 21, 2024 at 9:32 AM AEST, Salil Mehta wrote:
>  > KVM vCPU creation is done once during the vCPU realization when Qemu
>  > vCPU thread is spawned. This is common to all the architectures as of now.
>  >
>  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  > vCPU object/context in Qemu is parked.
>  >
>  > Refactor architecture common logic so that some APIs could be reused
>  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  > Update new/old APIs with trace events. No functional change is intended
>  here.
>  >
>  > Signed-off-by: Salil Mehta 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Jonathan Cameron 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  > Reviewed-by: Vishnu Pajjuri 
>  > ---
>  >  accel/kvm/kvm-all.c| 97 -
>  -
>  >  accel/kvm/kvm-cpus.h   | 23 ++
>  >  accel/kvm/trace-events |  5 ++-
>  >  3 files changed, 92 insertions(+), 33 deletions(-)
>  >
>  > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  > c0be9f5eed..a8f93078dc 100644
>  > --- a/accel/kvm/kvm-all.c
>  > +++ b/accel/kvm/kvm-all.c
>  > @@ -340,14 +340,73 @@ err:
>  >  return ret;
>  >  }
>  >
>  > +void kvm_park_vcpu(CPUState *cpu)
>  > +{
>  > +struct KVMParkedVcpu *vcpu;
>  > +
>  > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +vcpu = g_malloc0(sizeof(*vcpu));
>  > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +vcpu->kvm_fd = cpu->kvm_fd;
>  > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  > +
>  > +int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id) {
>  > +struct KVMParkedVcpu *cpu;
>  > +
>  > +QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
>  > +if (cpu->vcpu_id == vcpu_id) {
>  > +int kvm_fd;
>  > +
>  > +trace_kvm_unpark_vcpu(vcpu_id);
>  
>  Just an aside, but unfortunately tracing is not entirely consistent.
>  Often a function-level trace point is done at the beginning of the function
>  regardless of the result. But I actually like this style of tracing at the 
> end and
>  providing result too. OTOH you don't see the -ENOENT case.
>  
>  In any case it's nice to have something here.


I can definitely move it to the end. You mean you wish to include the case where
vCPU was not found already parked?


>  
>  Other unforunate thing is some confusion between attaching a KVM
>  context for QEMU vCPU, and actually making the KVM_CREATE_VCPU ioctl
>  call, and kvm_create_vcpu is not the counterpart of kvm_destroy_vcpu,
>  etc.. It is not your fault the existing naming makes this a bit confusing.
>  Fortunately it's pretty well contained to small amount of code.
>  
>  I hate to nitpick it but since the functions are being exported, would it be 
> a
>  better name somthing like kvm_attach_vcpu()?
>  
>  Just a thought, but no big deal. Either way,


Sure, I'm getting your point but KVM does not supports destruction of KVM vCPUs
and hence as you rightly pointed creation and destruction legs at Qemu are
not symmetrical. 

Can we live with existing conventions for now otherwise this change can add a
noise to this patch?


>  
>  Reviewed-by: Nicholas Piggin 


Thank you.
Salil


>  
>  > +
>  > +QLIST_REMOVE(cpu, node);
>  > +kvm_fd = cpu->kvm_fd;
>  > +g_free(cpu);
>  > +return kvm_fd;
>  > +}
>  > +}
>  > +
>  > +return -ENOENT;
>  > +}
>  > +
>  > +int kvm_create_vcpu(CPUState *cpu)
>  > +{
>  > +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +KVMState *s = kvm_state;
>  > +int kvm_fd;
>  > +
>  > +/* check if the KVM vCPU already exist but is parked */
>  > +kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +/* vCPU not parked: create a new KVM vCPU */
>  > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu",
>  vcpu_id);
>  > +return kvm_fd;
>  > +}
>  > +}
>  > +
>  > +trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
>  > +
>  > +cpu->kvm_fd = kvm_fd;
>  > +cpu->kvm_state = s;
>  > +cpu->vcpu_dirty = true;
>  > +cpu->dirty_pages = 0;
>  > +cpu->throttle_us_per_full = 0;
>  > +
>  > +return 0;
>  > +}
>  > +
>  >  static int do_kvm_destroy_vcpu(CPUState *cpu)  {
>  >  KVMState *s = kvm_state;
>  >  long mmap_size;
>  > -struct KVMParkedVcpu *vcpu = NULL;
>  >  int ret = 0;
>  >
>  > -trace_kvm_destroy_vcpu();
>  

RE: [PATCH V10 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-21 Thread Salil Mehta via
>  From: Alex Bennée 
>  Sent: Tuesday, May 21, 2024 4:23 PM
>  To: Salil Mehta 
>  
>  Salil Mehta  writes:
>  
>  > Hi Alex,
>  >
>  >>  From: Alex Bennée 
>  >>  Sent: Tuesday, May 21, 2024 1:45 PM
>  >>  To: Salil Mehta 
>  >>
>  >>  Salil Mehta  writes:
>  >>
>  >>  > Add common function to help unregister the GDB register space.
>  >> This  > shall be done in context to the CPU unrealization.
>  >>  >
>  >>  > Signed-off-by: Salil Mehta   > Tested-by:
>  >> Vishnu Pajjuri   > Reviewed-by:  Gavin
>  >> Shan   > Tested-by: Xianglai Li
>  >>   > Tested-by: Miguel Luis
>  >>   > Reviewed-by: Shaoqin Huang
>  >>   > Reviewed-by: Vishnu Pajjuri
>  >>   > ---
>  >>  >  gdbstub/gdbstub.c  | 13 +
>  >>  >  hw/core/cpu-common.c   |  1 -
>  >>  >  include/exec/gdbstub.h |  6 ++  >  3 files changed, 19
>  >> insertions(+), 1 deletion(-)  >  > diff --git a/gdbstub/gdbstub.c
>  >> b/gdbstub/gdbstub.c index  > b3574997ea..1949b09240 100644  > ---
>  >> a/gdbstub/gdbstub.c  > +++ b/gdbstub/gdbstub.c  > @@ -617,6 +617,19
>  >> @@ void gdb_register_coprocessor(CPUState *cpu,
>  >>  >  }
>  >>  >  }
>  >>  >
>  >>  > +void gdb_unregister_coprocessor_all(CPUState *cpu) {
>  >>  > +/*
>  >>  > + * Safe to nuke everything. GDBRegisterState::xml is static const 
> char
>  >>  so
>  >>  > + * it won't be freed
>  >>  > + */
>  >>  > +g_array_free(cpu->gdb_regs, true);
>  >>  > +
>  >>  > +cpu->gdb_regs = NULL;
>  >>  > +cpu->gdb_num_regs = 0;
>  >>  > +cpu->gdb_num_g_regs = 0;
>  >>  > +}
>  >>  > +
>  >>  >  static void gdb_process_breakpoint_remove_all(GDBProcess *p)  {
>  >>  >  CPUState *cpu = gdb_get_first_cpu_in_process(p); diff --git
>  >>  > a/hw/core/cpu-common.c b/hw/core/cpu-common.c index  >
>  >> 0f0a247f56..e5140b4bc1 100644  > --- a/hw/core/cpu-common.c  > +++
>  >> b/hw/core/cpu-common.c  > @@ -274,7 +274,6 @@ static void
>  >> cpu_common_finalize(Object *obj)  {
>  >>  >  CPUState *cpu = CPU(obj);
>  >>  >
>  >>  > -g_array_free(cpu->gdb_regs, TRUE);
>  >>
>  >>  Is this patch missing something? As far as I can tell the new
>  >> function never  gets called.
>  >
>  >
>  > Above was causing double free because eventually this free'ng of
>  > 'gdb_regs' is being done in context to un-realization of ARM CPU. Function
>  ' gdb_unregister_coprocessor_all'
>  > will be used by loongson arch as well. Hence, I placed this newly
>  > added function in the arch agnostic patch-set
>  >
>  > https://lore.kernel.org/qemu-devel/20230926103654.34424-1-
>  salil.mehta@
>  > huawei.com/
>  >
>  > Another approach could be to keep it but make above free'ing as
>  conditional?
>  >
>  > /* in case architecture specific code did not do its job */ if
>  > (cpu->gdb_regs)
>  > g_array_free(cpu->gdb_regs, TRUE);
>  
>  No I don't object to moving it to a function. But I would expect the patch
>  that adds the function and plumbs it in to also be the patch that removes
>  the inline call. Otherwise the tree will be broken in behaviour between
>  patches.
>  

Ok.

>  Just make it clear in the header that the series needs the pre-requisite
>  patches.

Sure, I will also add it in the header of this patch. Though, I did mention
about such dependency in the cover letter for this entire series.


Pasting from the cover-letter:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v10

NOTE: For ARM, above will work in combination of the architecture specific part 
based on
RFC V2 [1]. This architecture specific patch-set RFC V3 shall be floated soon 
and is present
at below location

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc1


Thanks
Salil.

>  
>  --
>  Alex Bennée
>  Virtualisation Tech Lead @ Linaro


RE: [PATCH V10 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-21 Thread Salil Mehta via
Hi Alex,

>  From: Alex Bennée 
>  Sent: Tuesday, May 21, 2024 1:45 PM
>  To: Salil Mehta 
>  
>  Salil Mehta  writes:
>  
>  > Add common function to help unregister the GDB register space. This
>  > shall be done in context to the CPU unrealization.
>  >
>  > Signed-off-by: Salil Mehta 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  > Reviewed-by: Vishnu Pajjuri 
>  > ---
>  >  gdbstub/gdbstub.c  | 13 +
>  >  hw/core/cpu-common.c   |  1 -
>  >  include/exec/gdbstub.h |  6 ++
>  >  3 files changed, 19 insertions(+), 1 deletion(-)
>  >
>  > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index
>  > b3574997ea..1949b09240 100644
>  > --- a/gdbstub/gdbstub.c
>  > +++ b/gdbstub/gdbstub.c
>  > @@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
>  >  }
>  >  }
>  >
>  > +void gdb_unregister_coprocessor_all(CPUState *cpu) {
>  > +/*
>  > + * Safe to nuke everything. GDBRegisterState::xml is static const char
>  so
>  > + * it won't be freed
>  > + */
>  > +g_array_free(cpu->gdb_regs, true);
>  > +
>  > +cpu->gdb_regs = NULL;
>  > +cpu->gdb_num_regs = 0;
>  > +cpu->gdb_num_g_regs = 0;
>  > +}
>  > +
>  >  static void gdb_process_breakpoint_remove_all(GDBProcess *p)  {
>  >  CPUState *cpu = gdb_get_first_cpu_in_process(p); diff --git
>  > a/hw/core/cpu-common.c b/hw/core/cpu-common.c index
>  > 0f0a247f56..e5140b4bc1 100644
>  > --- a/hw/core/cpu-common.c
>  > +++ b/hw/core/cpu-common.c
>  > @@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)  {
>  >  CPUState *cpu = CPU(obj);
>  >
>  > -g_array_free(cpu->gdb_regs, TRUE);
>  
>  Is this patch missing something? As far as I can tell the new function never
>  gets called.


Above was causing double free because eventually this free'ng of 'gdb_regs' is 
being
done in context to un-realization of ARM CPU. Function ' 
gdb_unregister_coprocessor_all'
will be used by loongson arch as well. Hence, I placed this newly added function
in the arch agnostic patch-set 

https://lore.kernel.org/qemu-devel/20230926103654.34424-1-salil.me...@huawei.com/

Another approach could be to keep it but make above free'ing as conditional?

/* in case architecture specific code did not do its job */
if (cpu->gdb_regs)
g_array_free(cpu->gdb_regs, TRUE);


Best regards
Salil.


>  
>  >  qemu_lockcnt_destroy(>in_ioctl_lock);
>  >  qemu_mutex_destroy(>work_mutex);
>  >  }
>  > diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index
>  > eb14b91139..249d4d4bc8 100644
>  > --- a/include/exec/gdbstub.h
>  > +++ b/include/exec/gdbstub.h
>  > @@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
>  >gdb_get_reg_cb get_reg, gdb_set_reg_cb 
> set_reg,
>  >const GDBFeature *feature, int g_pos);
>  >
>  > +/**
>  > + * gdb_unregister_coprocessor_all() - unregisters supplemental set of
>  > +registers
>  > + * @cpu - the CPU associated with registers  */ void
>  > +gdb_unregister_coprocessor_all(CPUState *cpu);
>  > +
>  >  /**
>  >   * gdbserver_start: start the gdb server
>  >   * @port_or_device: connection spec for gdb
>  
>  --
>  Alex Bennée
>  Virtualisation Tech Lead @ Linaro


[PATCH V10 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-05-20 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V10 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-20 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
---
 gdbstub/gdbstub.c  | 13 +
 hw/core/cpu-common.c   |  1 -
 include/exec/gdbstub.h |  6 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b3574997ea..1949b09240 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_regs = 0;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 0f0a247f56..e5140b4bc1 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)
 {
 CPUState *cpu = CPU(obj);
 
-g_array_free(cpu->gdb_regs, TRUE);
 qemu_lockcnt_destroy(>in_ioctl_lock);
 qemu_mutex_destroy(>work_mutex);
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V10 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-20 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d043..240ee04369 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..60b160d0b4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -486,6 +486,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 struct CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 342b7a8fd4..146f17826a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V10 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-05-20 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index af2b6655d2..4c63514b16 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -343,9 +343,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -370,13 +371,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -700,9 +707,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..b73b136605 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1537,7 +1537,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 

[PATCH V10 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-05-20 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 473b37ba88..af2b6655d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -327,7 +327,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 54d3b4bf9d..63226b0040 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V10 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-05-20 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V10 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-20 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Vishnu Pajjuri 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/cpu.c  |  6 +-
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..473b37ba88 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -221,7 +221,11 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 const CPUArchIdList *id_list;
 int i;
 
-assert(mc->possible_cpu_arch_ids);
+/* hotplug might not be available for all types like x86/microvm etc. */
+if (!mc->possible_cpu_arch_ids) {
+return;
+}
+
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..54d3b4bf9d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } 

[PATCH V10 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-20 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
---
 accel/kvm/kvm-all.c| 97 --
 accel/kvm/kvm-cpus.h   | 23 ++
 accel/kvm/trace-events |  5 ++-
 3 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..a8f93078dc 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -340,14 +340,73 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+
+QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+int kvm_fd;
+
+trace_kvm_unpark_vcpu(vcpu_id);
+
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+return kvm_fd;
+}
+}
+
+return -ENOENT;
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +432,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -389,24 +445,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
-{
-struct KVMParkedVcpu *cpu;
-
-QLIST_FOREACH(cpu, >kvm_parked_vcpus, node) {
-if (cpu->vcpu_id == vcpu_id) {
-int kvm_fd;
-
-QLIST_REMOVE(cpu, node);
-kvm_fd = cpu->kvm_fd;
-g_free(cpu);
-return kvm_fd;
-}
-}
-
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
 {
 KVMState *s = kvm_state;
@@ -415,19 +453,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index ca40add32c..2e6bb38b5d 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -22,5 +22,28 @@ bool kvm_supports_guest_debug(void);
 int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, 

[PATCH V10 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-05-20 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v10

NOTE: For ARM, above will work in combination of the architecture specific part 
based on
RFC V2 [1]. This architecture specific patch-set RFC V3 shall be floated soon 
and is present
at below location

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc1


Revision History:

Patch-set  V9 -> V10
1. Addressed Nicholas Piggin's (IBM) & Philippe Mathieu-Daudé (Linaro) comments
   - carved out kvm_unpark_vcpu and added its trace
   - Widened the scope of the kvm_unpark_vcpu so that it can be used by generic 
framework
 being thought out
Link: 
https://lore.kernel.org/qemu-devel/20240519210620.228342-1-salil.me...@huawei.com/
Link: 
https://lore.kernel.org/qemu-devel/e94b0e14-efee-4050-9c9f-08382a36b...@linaro.org/

Patch-set  V8 -> V9
1. Addressed Vishnu Pajjuri's (Ampere) comments
   - Added kvm_fd to trace in kvm_create_vcpu
   - Some clean ups: arch vcpu-id and sbd variable
   - Added the missed initialization of cpu->gdb_num_regs
2. Addressed the commnet from Zhao Liu (Intel)
   - Make initialization of CPU Hotplug state conditional 
(possible_cpu_arch_ids!=NULL)
Link: 
https://lore.kernel.org/qemu-devel/2024031202.12992-1-salil.me...@huawei.com/

Patch-set V7 -> V8
1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/

Patch-set V1 -> V2
1. Addressed Alex Bennée's comments
   - Refactored the kvm_create_vcpu logic to get rid of goto
   - Added the docs for kvm_{create,park}_vcpu prototypes
   - Splitted the gdbstub and AddressSpace destruction change into separate 
patches
   - Added Reviewed-by tags for patches {2,10}
Link: 
https://lore.kernel.org/qemu-devel/20230929124304.13672-1-salil.me...@huawei.com/

References:

[1] 
https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/
[2] 

RE: [PATCH V9 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-20 Thread Salil Mehta via
>  From: Nicholas Piggin 
>  Sent: Monday, May 20, 2024 9:04 AM
>  
>  On Mon May 20, 2024 at 7:06 AM AEST, Salil Mehta wrote:
>  > KVM vCPU creation is done once during the vCPU realization when Qemu
>  > vCPU thread is spawned. This is common to all the architectures as of now.
>  >
>  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  > vCPU object/context in Qemu is parked.
>  >
>  > Refactor architecture common logic so that some APIs could be reused
>  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  > Update new/old APIs with trace events instead of DPRINTF. No functional
>  change is intended here.
>  

[...]

void kvm_park_vcpu(CPUState *cpu)
>  > +{
>  > +struct KVMParkedVcpu *vcpu;
>  > +
>  > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +vcpu = g_malloc0(sizeof(*vcpu));
>  > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +vcpu->kvm_fd = cpu->kvm_fd;
>  > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  
>  Could you move kvm_get_vcpu up here so it's next to kvm_park_vcpu, and
>  then you don't need to forward declare it. Call it kvm_unpark_vcpu() for
>  symmetry with park.


sorry I missed this part earlier and Phil also suggested the same. Yes, I can.


Thanks
Salil.

>  
>  Thanks,
>  Nick


RE: [PATCH V9 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-20 Thread Salil Mehta via
>  From: Nicholas Piggin 
>  Sent: Monday, May 20, 2024 9:19 AM
>  
>  On Mon May 20, 2024 at 7:06 AM AEST, Salil Mehta wrote:
>  > Virtual CPU Hot-unplug leads to unrealization of a CPU object. This
>  > also involves destruction of the CPU AddressSpace. Add common function
>  > to help destroy the CPU AddressSpace.
>  
>  Patches 6,7 seem okay to me. I would like to see a series where they get
>  used. Would it be possible to include at least a TCG user in your series? 
> That
>  would make it easier to review and test.


If you wish to play then you can use below repository which is V8 version of
architecture agnostic patch-set plus architecture dependent patch-set
stacked up together. This effectively RFC V2 rearranged with clear separation
of arch agnostic and specific parts and some review comments incorporated.

https://github.com/salil-mehta/qemu/commits/virt-cpuhp-armv8/rfc-v3-rc1/


It has TCG but it has some issues and hence we have disabled it for now. We are
working to fix it.


Thanks
Salil.

>  
>  Thanks,
>  Nick


RE: [PATCH V9 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-20 Thread Salil Mehta via
Hi Nick,

>  From: Nicholas Piggin 
>  Sent: Monday, May 20, 2024 9:04 AM
>  To: Salil Mehta ; qemu-devel@nongnu.org;
>  qemu-...@nongnu.org
>  
>  On Mon May 20, 2024 at 7:06 AM AEST, Salil Mehta wrote:
>  > KVM vCPU creation is done once during the vCPU realization when Qemu
>  > vCPU thread is spawned. This is common to all the architectures as of now.
>  >
>  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  > vCPU object/context in Qemu is parked.
>  >
>  > Refactor architecture common logic so that some APIs could be reused
>  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  > Update new/old APIs with trace events instead of DPRINTF. No functional
>  change is intended here.
>  
>  This is a nice cleanup and helps with ppc hotplug as well.


Thanks and glad that it is of help.


>  
>  Has there been any architecture code posted yet?


Yes, I created one in  April/early May.  It contains arch specific patch-set 
stacked up
on the arch agnostic patch-set V8. Arch specific patch-set contains patches 
from the
RFC V2 I floated last year. 

https://github.com/salil-mehta/qemu/commits/virt-cpuhp-armv8/rfc-v3-rc1/


As such, a complete code of RFC V2 was posted last year. There is no clear 
separation of
architecture agnostic and specific patch-set in this version. and can be found 
at below
repository.

https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/


I shall be floating RFC V3 soon which will have only ARM architecture specific 
part and
yes will also have TCG code but there are some issues to be fixed for TCG and 
we are
working towards it. Hence, we have disabled TCG by default for now.


Thanks
Salil.













>  
>  Just a few minor thing:
>  
>  >
>  > Signed-off-by: Salil Mehta 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Jonathan Cameron 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  > Reviewed-by: Vishnu Pajjuri 
>  > ---
>  >  accel/kvm/kvm-all.c| 64 --
>  
>  >  accel/kvm/kvm-cpus.h   | 14 +
>  >  accel/kvm/trace-events |  5 +++-
>  >  3 files changed, 67 insertions(+), 16 deletions(-)
>  >
>  > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  > c0be9f5eed..9cd7d69bde 100644
>  > --- a/accel/kvm/kvm-all.c
>  > +++ b/accel/kvm/kvm-all.c
>  > @@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;  #define
>  > kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >
>  >  static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  > +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  >
>  >  static inline void kvm_resample_fd_remove(int gsi)  { @@ -340,14
>  > +341,53 @@ err:
>  >  return ret;
>  >  }
>  >
>  > +void kvm_park_vcpu(CPUState *cpu)
>  > +{
>  > +struct KVMParkedVcpu *vcpu;
>  > +
>  > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +vcpu = g_malloc0(sizeof(*vcpu));
>  > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +vcpu->kvm_fd = cpu->kvm_fd;
>  > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  
>  Could you move kvm_get_vcpu up here so it's next to kvm_park_vcpu, and
>  then you don't need to forward declare it. Call it kvm_unpark_vcpu() for
>  symmetry with park.
>  
>  Thanks,
>  Nick


[PATCH V9 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-05-19 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V9 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-05-19 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 473b37ba88..af2b6655d2 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -327,7 +327,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 54d3b4bf9d..63226b0040 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V9 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-19 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
---
 gdbstub/gdbstub.c  | 13 +
 hw/core/cpu-common.c   |  1 -
 include/exec/gdbstub.h |  6 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b3574997ea..1949b09240 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -617,6 +617,19 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_regs = 0;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 0f0a247f56..e5140b4bc1 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -274,7 +274,6 @@ static void cpu_common_finalize(Object *obj)
 {
 CPUState *cpu = CPU(obj);
 
-g_array_free(cpu->gdb_regs, TRUE);
 qemu_lockcnt_destroy(>in_ioctl_lock);
 qemu_mutex_destroy(>work_mutex);
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V9 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-19 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d043..240ee04369 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..60b160d0b4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -486,6 +486,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 struct CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 342b7a8fd4..146f17826a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V9 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-05-19 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index af2b6655d2..4c63514b16 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -343,9 +343,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -370,13 +371,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -700,9 +707,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..b73b136605 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1537,7 +1537,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 

[PATCH V9 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-19 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Vishnu Pajjuri 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/cpu.c  |  6 +-
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..473b37ba88 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -221,7 +221,11 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 const CPUArchIdList *id_list;
 int i;
 
-assert(mc->possible_cpu_arch_ids);
+/* hotplug might not be available for all types like x86/microvm etc. */
+if (!mc->possible_cpu_arch_ids) {
+return;
+}
+
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..54d3b4bf9d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } 

[PATCH V9 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-05-19 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git 
virt-cpuhp-armv8/rfc-v3.arch.agnostic.v9

NOTE: For ARM, above will work in combination of the architecture specific part 
based on
RFC V2 [1]. This architecture specific patch-set RFC V3 shall be floated soon 
and is present
at below location

[*] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v3-rc1


Revision History:

Patch-set  V8 -> V9
1. Addressed Vishnu Pajjuri's (Ampere) comments
   - Added kvm_fd to trace in kvm_create_vcpu
   - Some clean ups: arch vcpu-id and sbd variable
   - Added the missed initialization of cpu->gdb_num_regs
2. Addressed the commnet from Zhao Liu (Intel)
   - Make initialization of CPU Hotplug state conditional 
(possible_cpu_arch_ids!=NULL)
Link: 
https://lore.kernel.org/qemu-devel/2024031202.12992-1-salil.me...@huawei.com/

Patch-set V7 -> V8
1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/

Patch-set V1 -> V2
1. Addressed Alex Bennée's comments
   - Refactored the kvm_create_vcpu logic to get rid of goto
   - Added the docs for kvm_{create,park}_vcpu prototypes
   - Splitted the gdbstub and AddressSpace destruction change into separate 
patches
   - Added Reviewed-by tags for patches {2,10}
Link: 
https://lore.kernel.org/qemu-devel/20230929124304.13672-1-salil.me...@huawei.com/

References:

[1] 
https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/
[2] https://lore.kernel.org/all/20230913163823.7880-1-james.mo...@arm.com/
[3] 
https://lore.kernel.org/qemu-devel/cover.1695697701.git.lixiang...@loongson.cn/



Salil Mehta (8):
  accel/kvm: Extract common KVM vCPU {creation,parking} code
  hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
  hw/acpi: Update ACPI GED framework to support vCPU Hotplug
  hw/acpi: Update GED _EVT method AML with CPU scan
  hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
  physmem: Add helper function to destroy 

[PATCH V9 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-05-19 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V9 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-19 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events instead of DPRINTF. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
Reviewed-by: Vishnu Pajjuri 
---
 accel/kvm/kvm-all.c| 64 --
 accel/kvm/kvm-cpus.h   | 14 +
 accel/kvm/trace-events |  5 +++-
 3 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c0be9f5eed..9cd7d69bde 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
 
 static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -340,14 +341,53 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_get_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -373,10 +413,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -397,6 +434,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 if (cpu->vcpu_id == vcpu_id) {
 int kvm_fd;
 
+trace_kvm_get_vcpu(vcpu_id);
+
 QLIST_REMOVE(cpu, node);
 kvm_fd = cpu->kvm_fd;
 g_free(cpu);
@@ -404,7 +443,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 }
 }
 
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+return -ENOENT;
 }
 
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -415,19 +454,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index ca40add32c..ba5bea5bca 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -22,5 +22,19 @@ bool kvm_supports_guest_debug(void);
 int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
 int kvm_remove_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
 void kvm_remove_all_breakpoints(CPUState *cpu);
+/**
+ * kvm_create_vcpu - Gets a parked KVM vCPU 

RE: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-17 Thread Salil Mehta via
Hi Nick,

>  From: Nicholas Piggin 
>  Sent: Friday, May 17, 2024 4:44 AM
>  
>  On Thu May 16, 2024 at 11:35 PM AEST, Salil Mehta wrote:
>  >
>  > >  From: Harsh Prateek Bora 
>  > >  Sent: Thursday, May 16, 2024 2:07 PM
>  > >
>  > >  Hi Salil,
>  > >
>  > >  On 5/16/24 17:42, Salil Mehta wrote:
>  > >  > Hi Harsh,
>  > >  >
>  > >  >>   From: Harsh Prateek Bora 
>  > >  >>   Sent: Thursday, May 16, 2024 11:15 AM
>  > >  >>
>  > >  >>   Hi Salil,
>  > >  >>
>  > >  >>   Thanks for your email.
>  > >  >>   Your patch 1/8 is included here based on review comments on my 
> previous
>  > >  >>   patch from one of the maintainers in the community and therefore I 
>  had
>  > >  >>   kept you in CC to be aware of the desire of having this 
> independent patch to
>  > >  >>   get merged earlier even if your other patches in the series may go 
> through
>  > >  >>   further reviews.
>  > >  >
>  > >  > I really don’t know which discussion are  you pointing at? Please
>  > > > understand you are fixing a bug and we are pushing a feature which has 
> got large series.
>  > >  > It will break the patch-set  which is about t be merged.
>  > >  >
>  > >  > There will be significant overhead of testing on us for the work
>  > > we  > have been carrying forward for large time. This will be 
> disruptive. Please dont!
>  > >  >
>  > >
>  > >  I was referring to the review discussion on my prev patch here:
>  > >
>  > > https://lore.kernel.org/qemu-devel/d191d2jfar7l.2eh4s445m4...@gmail.com/
>  >
>  >
>  > Sure, I'm, not sure what this means.
>  >
>  >
>  > >  Although your patch was included with this series only to
>  > > facilitate review of  the additional patches depending on just one of 
> your patch.
>  >
>  >
>  > Generally you rebase your patch-set over the other and clearly state
>  > on the cover letter that this patch-set is dependent upon such and
>  > such patch-set. Just imagine if everyone starts to unilaterally pick
>  > up patches from each other's patch-set it will create a chaos not only for
>  the feature owners but also for the maintainers.
>  >
>  >
>  > >
>  > >  I am not sure what is appearing disruptive here. It is a common
>  > > practive in  the community that maintainer(s) can pick individual
>  > > patches from the  series if it has been vetted by siginificant number of 
> reviewers.
>  >
>  >
>  > Don’t you think this patch-set is asking for acceptance for a patch
>  > already part of another patch-set which is about to be accepted and is a 
> bigger feature?
>  > Will it cause maintenance overhead at the last moment? Yes, of course!
>  >
>  >
>  > >  However, in this case, since you have mentioned to post next
>  > > version soon,  you need not worry about it as that would be the
>  > > preferred version for both  of the series.
>  >
>  >
>  > Yes, but please understand we are working for the benefit of overall 
> community.
>  > Please cooperate here.
>  
>  There might be a misunderstanding, Harsh just said there had not been
>  much progress on your series for a while and he wasn't sure what the status
>  was. I mentioned that we *could* take your patch 1 (with your
>  blessing) if there was a hold up with the rest of the series. He was going to
>  check in with you to see how it was going.


Thanks for the clarification. No issues. I'm planning to float V9 of this 
series by
Monday and perhaps that’s all you want. 

As such, new cycle started on 23rd April and we had been busy rebasing and
testing. This series works in conjunction with other series. We have to ensure 
both
are compatible.


>  This patch 1 was not intended to be merged as is without syncing up with
>  you first, but it's understandable you were concerned because that was
>  probably not communicated with you clearly.


No issues. I think we all are in the same page now. I understand your
requirement. We are trying our best to expedite acceptance of this series.
Perhaps your reviews on V9 might help.


>  
>  I appreciate you bringing up your concerns, we'll try to do better.

No problem. Thanks

Salil.

>  
>  Thanks,
>  Nick


RE: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Salil Mehta via

>  From: Harsh Prateek Bora 
>  Sent: Thursday, May 16, 2024 2:07 PM
>  
>  Hi Salil,
>  
>  On 5/16/24 17:42, Salil Mehta wrote:
>  > Hi Harsh,
>  >
>  >>   From: Harsh Prateek Bora 
>  >>   Sent: Thursday, May 16, 2024 11:15 AM
>  >>
>  >>   Hi Salil,
>  >>
>  >>   Thanks for your email.
>  >>   Your patch 1/8 is included here based on review comments on my  previous
>  >>   patch from one of the maintainers in the community and therefore I  had
>  >>   kept you in CC to be aware of the desire of having this independent 
> patch to
>  >>   get merged earlier even if your other patches in the series may go 
> through
>  >>   further reviews.
>  >
>  > I really don’t know which discussion are  you pointing at? Please
>  > understand you are fixing a bug and we are pushing a feature which has got 
> large series.
>  > It will break the patch-set  which is about t be merged.
>  >
>  > There will be significant overhead of testing on us for the work we
>  > have been carrying forward for large time. This will be disruptive. Please 
> dont!
>  >
>  
>  I was referring to the review discussion on my prev patch here:
>  https://lore.kernel.org/qemu-devel/d191d2jfar7l.2eh4s445m4...@gmail.com/


Sure, I'm, not sure what this means. 


>  Although your patch was included with this series only to facilitate review 
> of
>  the additional patches depending on just one of your patch.


Generally you rebase your patch-set over the other and clearly state on the 
cover
letter that this patch-set is dependent upon such and such patch-set. Just 
imagine
if everyone starts to unilaterally pick up patches from each other's patch-set 
it will
create a chaos not only for the feature owners but also for the maintainers.


>  
>  I am not sure what is appearing disruptive here. It is a common practive in
>  the community that maintainer(s) can pick individual patches from the
>  series if it has been vetted by siginificant number of reviewers.


Don’t you think this patch-set is asking for acceptance for a patch already 
part of another patch-set which is about to be accepted and is a bigger feature?
Will it cause maintenance overhead at the last moment? Yes, of course!


>  However, in this case, since you have mentioned to post next version soon,
>  you need not worry about it as that would be the preferred version for both
>  of the series.


Yes, but please understand we are working for the benefit of overall community.
Please cooperate here.

>  
>  >
>  >>
>  >>   I am hoping to see your v9 soon and thereafter maintainer(s) may
>  choose to
>  >>   pick the latest independent patch if needs to be merged earlier.
>  >
>  >
>  > I don’t think you are understanding what problem it is causing. For
>  > your small bug fix you are causing significant delays at our end.
>  >
>  
>  I hope I clarfied above that including your patch here doesnt delay anything.
>  Hoping to see your v9 soon!
>  
>  Thanks
>  Harsh
>  >
>  > Thanks
>  > Salil.
>  >>
>  >>   Thanks for your work and let's be hopeful it gets merged soon.
>  >>
>  >>   regards,
>  >>   Harsh
>  >>
>  >>   On 5/16/24 14:00, Salil Mehta wrote:
>  >>   > Hi Harsh,
>  >>   >
>  >>   > Thanks for your interest in the patch-set but taking away patches like
>  >>   > this from other series without any discussion can disrupt others work
>  >>   > and its acceptance on time. This is because we will have to put lot of
>  >>   > effort in rebasing bigger series and then testing overhead comes
>  along
>  >>   > with it.
>  >>   >
>  >>   > The patch-set (from where this  patch has been taken) is part of even
>  >>   > bigger series and there have been many people and companies toiling
>  to
>  >>   > fix the bugs collectively in that series and for years.
>  >>   >
>  >>   > I'm about float the V9 version of the Arch agnostic series which this
>  >>   > patch is part of and you can rebase your patch-set from there. I'm
>  >>   > hopeful that it will get accepted in this cycle.
>  >>   >
>  >>   >
>  >>   > Many thanks
>  >>   > Salil.
>  >>   >
>  >>   >>   From: Harsh Prateek Bora 
>  >>   >>   Sent: Thursday, May 16, 2024 6:32 AM
>  >>   >>
>  >>   >>   From: Salil Mehta 
>  >>   >>
>  >>   >>   KVM vCPU creation is done once during the vCPU realization when
>  >>   Qemu
>  >>   >>   vCPU thread is spawned. This is common to all the architectures as
>  of
>  >>   now.
>  >>   >>
>  >>   >>   Hot-unplug of vCPU results in destruction of the vCPU object in
>  QOM
>  >>   but
>  >>   >>   the corresponding KVM vCPU object in the Host KVM is not
>  destroyed
>  >>   as
>  >>   >>   KVM doesn't support vCPU removal. Therefore, its representative
>  KVM
>  >>   >>   vCPU object/context in Qemu is parked.
>  >>   >>
>  >>   >>   Refactor architecture common logic so that some APIs could be
>  reused
>  >>   by
>  >>   >>   vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  >>   Update
>  >>   >>   new/old APIs with trace events instead of DPRINTF. No functional
>  

RE: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Salil Mehta via
Hi Harsh,

>  From: Harsh Prateek Bora 
>  Sent: Thursday, May 16, 2024 11:15 AM
>  
>  Hi Salil,
>  
>  Thanks for your email.
>  Your patch 1/8 is included here based on review comments on my previous
>  patch from one of the maintainers in the community and therefore I had
>  kept you in CC to be aware of the desire of having this independent patch to
>  get merged earlier even if your other patches in the series may go through
>  further reviews.

I really don’t know which discussion are  you pointing at? Please understand
you are fixing a bug and we are pushing a feature which has got large series.
It will break the patch-set  which is about t be merged.

There will be significant overhead of testing on us for the work we have been
carrying forward for large time. This will be disruptive. Please dont!


>  
>  I am hoping to see your v9 soon and thereafter maintainer(s) may choose to
>  pick the latest independent patch if needs to be merged earlier.


I don’t think you are understanding what problem it is causing. For your
small bug fix you are causing significant delays at our end.


Thanks
Salil.
>  
>  Thanks for your work and let's be hopeful it gets merged soon.
>  
>  regards,
>  Harsh
>  
>  On 5/16/24 14:00, Salil Mehta wrote:
>  > Hi Harsh,
>  >
>  > Thanks for your interest in the patch-set but taking away patches like
>  > this from other series without any discussion can disrupt others work
>  > and its acceptance on time. This is because we will have to put lot of
>  > effort in rebasing bigger series and then testing overhead comes along
>  > with it.
>  >
>  > The patch-set (from where this  patch has been taken) is part of even
>  > bigger series and there have been many people and companies toiling to
>  > fix the bugs collectively in that series and for years.
>  >
>  > I'm about float the V9 version of the Arch agnostic series which this
>  > patch is part of and you can rebase your patch-set from there. I'm
>  > hopeful that it will get accepted in this cycle.
>  >
>  >
>  > Many thanks
>  > Salil.
>  >
>  >>   From: Harsh Prateek Bora 
>  >>   Sent: Thursday, May 16, 2024 6:32 AM
>  >>
>  >>   From: Salil Mehta 
>  >>
>  >>   KVM vCPU creation is done once during the vCPU realization when
>  Qemu
>  >>   vCPU thread is spawned. This is common to all the architectures as of
>  now.
>  >>
>  >>   Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  but
>  >>   the corresponding KVM vCPU object in the Host KVM is not destroyed
>  as
>  >>   KVM doesn't support vCPU removal. Therefore, its representative KVM
>  >>   vCPU object/context in Qemu is parked.
>  >>
>  >>   Refactor architecture common logic so that some APIs could be reused
>  by
>  >>   vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  Update
>  >>   new/old APIs with trace events instead of DPRINTF. No functional
>  change is
>  >>   intended here.
>  >>
>  >>   Signed-off-by: Salil Mehta 
>  >>   Reviewed-by: Gavin Shan 
>  >>   Tested-by: Vishnu Pajjuri 
>  >>   Reviewed-by: Jonathan Cameron 
>  >>   Tested-by: Xianglai Li 
>  >>   Tested-by: Miguel Luis 
>  >>   Reviewed-by: Shaoqin Huang 
>  >>   [harshpb: fixed rebase failures in include/sysemu/kvm.h]
>  >>   Signed-off-by: Harsh Prateek Bora 
>  >>   ---
>  >>include/sysemu/kvm.h   | 15 ++
>  >>accel/kvm/kvm-all.c| 64 ---
>  -
>  >>   --
>  >>accel/kvm/trace-events |  5 +++-
>  >>3 files changed, 68 insertions(+), 16 deletions(-)
>  >>
>  >>   diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index
>  >>   eaf801bc93..fa3ec74442 100644
>  >>   --- a/include/sysemu/kvm.h
>  >>   +++ b/include/sysemu/kvm.h
>  >>   @@ -434,6 +434,21 @@ void kvm_set_sigmask_len(KVMState *s,
>  unsigned
>  >>   int sigmask_len);
>  >>
>  >>int kvm_physical_memory_addr_from_host(KVMState *s, void
>  >>   *ram_addr,
>  >>   hwaddr *phys_addr);
>  >>   +/**
>  >>   + * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM
>  vCPU
>  >>   + * @cpu: QOM CPUState object for which KVM vCPU has to be
>  >>   fetched/created.
>  >>   + *
>  >>   + * @returns: 0 when success, errno (<0) when failed.
>  >>   + */
>  >>   +int kvm_create_vcpu(CPUState *cpu);
>  >>   +
>  >>   +/**
>  >>   + * kvm_park_vcpu - Park QEMU KVM vCPU context
>  >>   + * @cpu: QOM CPUState object for which QEMU KVM vCPU context
>  has to
>  >>   be parked.
>  >>   + *
>  >>   + * @returns: none
>  >>   + */
>  >>   +void kvm_park_vcpu(CPUState *cpu);
>  >>
>  >>#endif /* COMPILING_PER_TARGET */
>  >>
>  >>   diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  >>   d7281b93f3..30d42847de 100644
>  >>   --- a/accel/kvm/kvm-all.c
>  >>   +++ b/accel/kvm/kvm-all.c
>  >>   @@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;  #define
>  >>   kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >>
>  >>static void kvm_slot_init_dirty_bitmap(KVMSlot 

RE: [PATCH v2 1/4] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-16 Thread Salil Mehta via
Hi Harsh,

Thanks for your interest in the patch-set but taking away patches like
this from other series without any discussion can disrupt others work
and its acceptance on time. This is because we will have to put lot of
effort in rebasing bigger series and then testing overhead comes along
with it.

The patch-set (from where this  patch has been taken) is part of even
bigger series and there have been many people and companies toiling
to fix the bugs collectively in that series and for years.

I'm about float the V9 version of the Arch agnostic series which this
patch is part of and you can rebase your patch-set from there. I'm
hopeful that it will get accepted in this cycle.


Many thanks
Salil.

>  From: Harsh Prateek Bora 
>  Sent: Thursday, May 16, 2024 6:32 AM
>  
>  From: Salil Mehta 
>  
>  KVM vCPU creation is done once during the vCPU realization when Qemu
>  vCPU thread is spawned. This is common to all the architectures as of now.
>  
>  Hot-unplug of vCPU results in destruction of the vCPU object in QOM but
>  the corresponding KVM vCPU object in the Host KVM is not destroyed as
>  KVM doesn't support vCPU removal. Therefore, its representative KVM
>  vCPU object/context in Qemu is parked.
>  
>  Refactor architecture common logic so that some APIs could be reused by
>  vCPU Hotplug code of some architectures likes ARM, Loongson etc. Update
>  new/old APIs with trace events instead of DPRINTF. No functional change is
>  intended here.
>  
>  Signed-off-by: Salil Mehta 
>  Reviewed-by: Gavin Shan 
>  Tested-by: Vishnu Pajjuri 
>  Reviewed-by: Jonathan Cameron 
>  Tested-by: Xianglai Li 
>  Tested-by: Miguel Luis 
>  Reviewed-by: Shaoqin Huang 
>  [harshpb: fixed rebase failures in include/sysemu/kvm.h]
>  Signed-off-by: Harsh Prateek Bora 
>  ---
>   include/sysemu/kvm.h   | 15 ++
>   accel/kvm/kvm-all.c| 64 
>  --
>   accel/kvm/trace-events |  5 +++-
>   3 files changed, 68 insertions(+), 16 deletions(-)
>  
>  diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index
>  eaf801bc93..fa3ec74442 100644
>  --- a/include/sysemu/kvm.h
>  +++ b/include/sysemu/kvm.h
>  @@ -434,6 +434,21 @@ void kvm_set_sigmask_len(KVMState *s, unsigned
>  int sigmask_len);
>  
>   int kvm_physical_memory_addr_from_host(KVMState *s, void
>  *ram_addr,
>  hwaddr *phys_addr);
>  +/**
>  + * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
>  + * @cpu: QOM CPUState object for which KVM vCPU has to be
>  fetched/created.
>  + *
>  + * @returns: 0 when success, errno (<0) when failed.
>  + */
>  +int kvm_create_vcpu(CPUState *cpu);
>  +
>  +/**
>  + * kvm_park_vcpu - Park QEMU KVM vCPU context
>  + * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to
>  be parked.
>  + *
>  + * @returns: none
>  + */
>  +void kvm_park_vcpu(CPUState *cpu);
>  
>   #endif /* COMPILING_PER_TARGET */
>  
>  diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  d7281b93f3..30d42847de 100644
>  --- a/accel/kvm/kvm-all.c
>  +++ b/accel/kvm/kvm-all.c
>  @@ -128,6 +128,7 @@ static QemuMutex kml_slots_lock;  #define
>  kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  
>   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  
>   static inline void kvm_resample_fd_remove(int gsi)  { @@ -340,14 +341,53
>  @@ err:
>   return ret;
>   }
>  
>  +void kvm_park_vcpu(CPUState *cpu)
>  +{
>  +struct KVMParkedVcpu *vcpu;
>  +
>  +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  +
>  +vcpu = g_malloc0(sizeof(*vcpu));
>  +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  +vcpu->kvm_fd = cpu->kvm_fd;
>  +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  +
>  +int kvm_create_vcpu(CPUState *cpu)
>  +{
>  +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  +KVMState *s = kvm_state;
>  +int kvm_fd;
>  +
>  +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  +
>  +/* check if the KVM vCPU already exist but is parked */
>  +kvm_fd = kvm_get_vcpu(s, vcpu_id);
>  +if (kvm_fd < 0) {
>  +/* vCPU not parked: create a new KVM vCPU */
>  +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  +if (kvm_fd < 0) {
>  +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu",
>  vcpu_id);
>  +return kvm_fd;
>  +}
>  +}
>  +
>  +cpu->kvm_fd = kvm_fd;
>  +cpu->kvm_state = s;
>  +cpu->vcpu_dirty = true;
>  +cpu->dirty_pages = 0;
>  +cpu->throttle_us_per_full = 0;
>  +
>  +return 0;
>  +}
>  +
>   static int do_kvm_destroy_vcpu(CPUState *cpu)  {
>   KVMState *s = kvm_state;
>   long mmap_size;
>  -struct KVMParkedVcpu *vcpu = NULL;
>   int ret = 0;
>  
>  -trace_kvm_destroy_vcpu();
>  +trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  
>   ret = 

RE: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-08 Thread Salil Mehta via
Hi Phillipe,

Sorry, I missed this mail earlier.

>  From: Philippe Mathieu-Daudé 
>  Sent: Friday, May 3, 2024 7:23 PM
>  To: Salil Mehta ; qemu-devel@nongnu.org;
>  qemu-...@nongnu.org
>  
>  On 3/5/24 17:57, Salil Mehta wrote:
>  > Hi Philippe,
>  >
>  >>   From: Philippe Mathieu-Daudé 
>  >>   Sent: Friday, May 3, 2024 10:40 AM
>  >>   Subject: Re: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU
>  >>   {creation,parking} code
>  >>
>  >>   Hi Salil,
>  >>
>  >>   On 12/3/24 02:59, Salil Mehta wrote:
>  >>   > KVM vCPU creation is done once during the vCPU realization when Qemu
>  >>   > vCPU thread is spawned. This is common to all the architectures as of 
> now.
>  >>   >
>  >>   > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  >>   > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  >>   > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  >>   > vCPU object/context in Qemu is parked.
>  >>   >
>  >>   > Refactor architecture common logic so that some APIs could be reused
>  >>   > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  >>   > Update new/old APIs with trace events instead of DPRINTF. No 
> functional
>  >>   change is intended here.
>  >>   >
>  >>   > Signed-off-by: Salil Mehta 
>  >>   > Reviewed-by: Gavin Shan 
>  >>   > Tested-by: Vishnu Pajjuri 
>  >>   > Reviewed-by: Jonathan Cameron 
>  >>   > Tested-by: Xianglai Li 
>  >>   > Tested-by: Miguel Luis 
>  >>   > Reviewed-by: Shaoqin Huang 
>  >>   > ---
>  >>   >   accel/kvm/kvm-all.c| 64 -
>  -
>  >>   
>  >>   >   accel/kvm/trace-events |  5 +++-
>  >>   >   include/sysemu/kvm.h   | 16 +++
>  >>   >   3 files changed, 69 insertions(+), 16 deletions(-)
>  >>   >
>  >>   > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  >>   > a8cecd040e..3bc3207bda 100644
>  >>   > --- a/accel/kvm/kvm-all.c
>  >>   > +++ b/accel/kvm/kvm-all.c
>  >>   > @@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
>  >>   >   #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >>   >
>  >>   >   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  >>   > +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  >>   >
>  >>   >   static inline void kvm_resample_fd_remove(int gsi)
>  >>   >   {
>  >>   > @@ -314,14 +315,53 @@ err:
>  >>   >   return ret;
>  >>   >   }
>  >>   >
>  >>   > +void kvm_park_vcpu(CPUState *cpu)
>  >>   > +{
>  >>   > +struct KVMParkedVcpu *vcpu;
>  >>   > +
>  >>   > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  >>   > +
>  >>   > +vcpu = g_malloc0(sizeof(*vcpu));
>  >>   > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  >>   > +vcpu->kvm_fd = cpu->kvm_fd;
>  >>   > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  >>   > +
>  >>   > +int kvm_create_vcpu(CPUState *cpu)
>  >>   > +{
>  >>   > +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  >>   > +KVMState *s = kvm_state;
>  >>   > +int kvm_fd;
>  >>   > +
>  >>   > +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  >>   > +
>  >>   > +/* check if the KVM vCPU already exist but is parked */
>  >>   > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
>  >>   > +if (kvm_fd < 0) {
>  >>   > +/* vCPU not parked: create a new KVM vCPU */
>  >>   > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  >>   > +if (kvm_fd < 0) {
>  >>   > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU 
> %lu", vcpu_id);
>  >>   > +return kvm_fd;
>  >>   > +}
>  >>   > +}
>  >>   > +
>  >>   > +cpu->kvm_fd = kvm_fd;
>  >>   > +cpu->kvm_state = s;
>  >>   > +cpu->vcpu_dirty = true;
>  >>   > +cpu->dirty_pages = 0;
>  >>   > +cpu->throttle_us_per_full = 0;
>  >>   > +
>  >>   > +return 0;
>  >>   > +}
>  >>
>  >>   This seems generic enough to be implemented for all accelerators.
>  >>
>  >>   See AccelOpsClass in include/sysemu/accel-ops.h.
>  >>
>  >>   That said, can be done later on top.
>  >
>  > Let me understand correctly. Are you suggesting to implement above
>  > even for HVF, TCG, QTEST etc?
>  
>  Not for you to implement the other non-KVM accelerators, but since you
>  are introducing this, now is a good time to think about a generic interface.
>  
>  So far AccelOpsClass::[un]park_vcpu() handlers make sense to me.

Sure, but what is the advantage of defining these 'supporting' functions
as part of the AccelOpsClass? Each of these functions in any case will need
to be defined individually for different Accelerators or unless we are
planning to extract some common accelerator functions in a separate file
and use them across all the accelerators?

I'm surely missing some key point here.

Thanks
Salil.







RE: [PATCH V8 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-07 Thread Salil Mehta via
Hi Peter,

>  From: Peter Maydell 
>  Sent: Tuesday, May 7, 2024 10:03 AM
>  
>  On Tue, 7 May 2024 at 01:11, Salil Mehta  wrote:
>  >
>  > >  From: Peter Maydell 
>  > >  Sent: Monday, May 6, 2024 10:29 AM
>  > >  To: Salil Mehta 
>  > >
>  > >  On Mon, 6 May 2024 at 10:06, Salil Mehta 
>  > >  wrote:
>  > >  >
>  > >  > Hi Peter,
>  > >  >
>  > >  > Thanks for the review.
>  > >  >
>  > >  > >  From: Peter Maydell   When do we
>  > > need to  > > destroy a single address space in this way that means
>  > > we need to  > > keep a count of how many ASes the CPU currently has?
>  > > The  commit  > > message talks about the case when we unrealize the
>  > > whole CPU  > > object, but in that situation you can just throw away
>  > > all the ASes  > > at once (eg  by calling some  > >
>  > > cpu_destroy_address_spaces() function from
>  > > cpu_common_unrealizefn()).
>  > >  >
>  > >  >
>  > >  > Yes, maybe, we can destroy all at once from common leg as well.
>  > > I'd  > prefer this to be done from the arch specific function for
>  > > ARM to  > maintain the clarity & symmetry of initialization and  >
>  > > un-initialization legs.  For now, all of these address space
>  > > destruction is  happening in context to the arm_cpu_unrealizefn().
>  > >  >
>  > >  > It’s a kind of trade-off between little more code and clarity but
>  > > I'm  > open to further suggestions.
>  > >  >
>  > >  >
>  > >  > >
>  > >  > >  Also, if we're leaking stuff here by failing to destroy it, is
>  > > that  > > a problem for  existing CPU types like x86 that we can already 
>  hotplug?
>  > >  >
>  > >  > No we are not. We are taking care of these in the ARM arch
>  > > specific  > legs within functions arm_cpu_(un)realizefn().
>  > >
>  > >  How can you be taking care of *x86* CPU types in the Arm unrealize?
>  >
>  >
>  > Sorry, yes, I missed to reply that clearly. There was indeed a leak
>  > with x86 reported by Phillipe/David last year. In fact, Phillipe floated a
>  patch last year for this.
>  > I thought it was fixed already as part of cpu_common_unrealize() but I
>  > just checked and realized that the below proposed changed still isn’t
>  > part of the mainline
>  >
>  > https://lore.kernel.org/qemu-devel/20230918160257.30127-9-
>  philmd@linar
>  > o.org/
>  
>  That seems like the right way to clean these up -- Philippe, do you want to
>  fish that bugfix out of your big patchset and submit it separately ?
>  
>  > I can definitely add a common CPU AddressSpace destruction leg as part
>  > of this patch if in case arch specific CPU unrealize does not cleans
>  > up its CPU AddressSpace?
>  
>  Arch-specific CPU unrealize shouldn't need to do anything -- if we fix this
>  similarly to Philippe's patch above then that will do the cleanup required.
>  Handling this kind of cleanup in common code is more reliable because it
>  doesn't require every target-arch maintainer to remember it needs to be
>  done, plus it's less code.


Agreed but It is a trade-off between 'lines of code' and 'clarity of the code'.
Ideally, if someone is adding a initialization part one must consciously verify
the locations where these will get deallocated/deinited as well so I do not
think there is an escape from that kind of maintenance part. 

For arch like x86, where we are doing default AddressSpace allocation from
common realize, it is more obvious to symmetrically destroy from common
leg but for any other architecture including ARM where many types of CPU
AddressSpace are getting allocated it would not be obvious to find its
destruction leg buried somewhere in the common code. 

Hence, I would suggest to make release of the AddressSpace from common
unrealization part optional which by default it is in the code excerpt from the
patch:

https://lore.kernel.org/qemu-devel/20230918160257.30127-9-phi...@linaro.org/

+/* Destroy CPU address space */
+for (unsigned idx = 0; idx < cpu->num_ases; idx++) {
+cpu_address_space_destroy(cpu, idx);
+}

cpu->num_ases will be 0 in case Arch specific code has already destroyed it.

That said we will still need some modification in the address space destruction
function to gracefully return in case that CPU AddressSpace was already
destroyed or does not exist. This will keep both options open.


Thanks
Salil.

>  
>  thanks
>  -- PMM


RE: [PATCH V8 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-06 Thread Salil Mehta via
>  From: Peter Maydell 
>  Sent: Monday, May 6, 2024 10:29 AM
>  To: Salil Mehta 
>  
>  On Mon, 6 May 2024 at 10:06, Salil Mehta 
>  wrote:
>  >
>  > Hi Peter,
>  >
>  > Thanks for the review.
>  >
>  > >  From: Peter Maydell   When do we need to
>  > > destroy a single address space in this way that means  we need to
>  > > keep a count of how many ASes the CPU currently has? The  commit
>  > > message talks about the case when we unrealize the whole CPU
>  > > object, but in that situation you can just throw away all the ASes
>  > > at once (eg  by calling some
>  > >  cpu_destroy_address_spaces() function from
>  cpu_common_unrealizefn()).
>  >
>  >
>  > Yes, maybe, we can destroy all at once from common leg as well. I'd
>  > prefer this to be done from the arch specific function for ARM to
>  > maintain the clarity & symmetry of initialization and
>  > un-initialization legs.  For now, all of these address space destruction is
>  happening in context to the arm_cpu_unrealizefn().
>  >
>  > It’s a kind of trade-off between little more code and clarity but I'm
>  > open to further suggestions.
>  >
>  >
>  > >
>  > >  Also, if we're leaking stuff here by failing to destroy it, is that
>  > > a problem for  existing CPU types like x86 that we can already hotplug?
>  >
>  > No we are not. We are taking care of these in the ARM arch specific
>  > legs within functions arm_cpu_(un)realizefn().
>  
>  How can you be taking care of *x86* CPU types in the Arm unrealize?


Sorry, yes, I missed to reply that clearly. There was indeed a leak with x86 
reported
by Phillipe/David last year. In fact, Phillipe floated a patch last year for 
this.
I thought it was fixed already as part of cpu_common_unrealize() but I just
checked and realized that the below proposed changed still isn’t part of the
mainline

https://lore.kernel.org/qemu-devel/20230918160257.30127-9-phi...@linaro.org/

I can definitely add a common CPU AddressSpace destruction leg as part of this
patch if in case arch specific CPU unrealize does not cleans up its CPU
AddressSpace?


Thanks
Salil.

>  
>  thanks
>  -- PMM


RE: [PATCH V8 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-06 Thread Salil Mehta via


>  From: Zhao Liu 
>  Sent: Monday, May 6, 2024 10:06 AM
>  
>  Hi Salil,
>  
>  On Fri, May 03, 2024 at 07:59:32PM +, Salil Mehta wrote:
>  > Date: Fri, 3 May 2024 19:59:32 +
>  > From: Salil Mehta 
>  > Subject: RE: [PATCH V8 3/8] hw/acpi: Update ACPI GED framework to
>  > support  vCPU Hotplug
>  >
>  > Hello,
>  >
>  > Sorry, I missed this earlier.
>  >
>  > >  From: Zhao Liu 
>  > >  Sent: Wednesday, March 13, 2024 6:14 AM
>  > >  To: Salil Mehta 
>  > >
>  > >  Hi Salil,
>  > >
>  > >  It seems my comment [1] in v7 was missed, but I still hit the same
>  > > issue. Pls  let me paste the previous comment here again.
>  > >
>  > >  [1]: https://lore.kernel.org/qemu- devel/zxcqp32ggifvu...@intel.com/
>  >
>  > Yes, I have this in my mind.
>  >
>  > >
>  > >  [snip]
>  > >
>  > >  > @@ -400,6 +411,12 @@ static void acpi_ged_initfn(Object *obj)
>  > >  >  memory_region_init_io(_st->regs, obj, _regs_ops,  ged_st,
>  > >  >TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
>  > >  >  sysbus_init_mmio(sbd, _st->regs);
>  > >  > +
>  > >  > +memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp
>  > >  container",
>  > >  > +   ACPI_CPU_HOTPLUG_REG_LEN);
>  > >  > +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
>  > >  > +cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
>  > >  > +>cpuhp_state, 0);
>  > >  >  }
>  > >  >
>  > >
>  > >  I find this cpu_hotplug_hw_init() can still cause qtest errors (for
>  > > v8) on x86  platforms as you mentioned in v6:
>  > >  
> https://lore.kernel.org/qemu-devel/15e70616-6abb-63a4-17d0-820f4a254...@opnsrc.net/T/#m108f102b2fe92b7dd7218f2f942f7b233a9d6af3
>  > >
>  > >  IIUC, microvm machine has its own 'possible_cpus_arch_ids' and that
>  > > is  inherited from its parent x86 machine.
>  > >
>  > >  The above error is because device-introspect-test sets the none-machine:
>  > >
>  > >  # starting QEMU: exec ./qemu-system-i386 -qtest unix:/tmp/qtest-
>  > > 3094820.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-
>  > >  3094820.qmp,id=char0 -mon chardev=char0,mode=control -display none
>  > > -  audio none -nodefaults -machine none -accel qtest
>  > >
>  > >  So what about just checking mc->possible_cpu_arch_ids instead of an
>  > > assert in cpu_hotplug_hw_init()?
>  > >
>  > >  diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index
>  > > 4b24a2500361..303f1f1f57bc 100644
>  > >  --- a/hw/acpi/cpu.c
>  > >  +++ b/hw/acpi/cpu.c
>  > >  @@ -221,7 +221,10 @@ void cpu_hotplug_hw_init(MemoryRegion *as,
>  > > Object *owner,
>  > >   const CPUArchIdList *id_list;
>  > >   int i;
>  > >
>  > >  -assert(mc->possible_cpu_arch_ids);
>  > >  +if (!mc->possible_cpu_arch_ids) {
>  > >  +return;
>  > >  +}
>  > >  +
>  >
>  >
>  > Yes, we can do this with some debug print or trace maybe.
>  
>  Here it is just to return early without touching mc->possible_cpu_arch_ids().
>  If you adopt this workaround, then in the meantime I suggest adding a
>  comment to this "if" to clarify that it is for compatibility with certain
>  machines that do not implement mc->possible_cpu_arch_ids().


sure.


>  
>  > >   id_list = mc->possible_cpu_arch_ids(machine);
>  > >   state->dev_count = id_list->len;
>  > >   state->devs = g_new0(typeof(*state->devs), state->dev_count);
>  > >
>  > >  This check seems to be acceptable in the general code path? Not all
>  > > machines have possible_cpu_arch_ids, after all.
>  >
>  > True. BTW, have you tested this with Qtest?
>  
>  Yes, by "make check" on x86 platform. This workaround can help us pass the
>  x86 tests.

thanks.

Best
Salil.





RE: [PATCH V8 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-05-06 Thread Salil Mehta via
Hi Peter,

Thanks for the review.

>  From: Peter Maydell 
>  Sent: Saturday, May 4, 2024 2:41 PM
>  
>  On Tue, 12 Mar 2024 at 02:02, Salil Mehta 
>  wrote:
>  >
>  > Virtual CPU Hot-unplug leads to unrealization of a CPU object. This
>  > also involves destruction of the CPU AddressSpace. Add common function
>  > to help destroy the CPU AddressSpace.
>  >
>  > Signed-off-by: Salil Mehta 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  
>  > diff --git a/system/physmem.c b/system/physmem.c index
>  > 6e9ed97597..61b32ac4f2 100644
>  > --- a/system/physmem.c
>  > +++ b/system/physmem.c
>  > @@ -761,6 +761,7 @@ void cpu_address_space_init(CPUState *cpu, int
>  > asidx,
>  >
>  >  if (!cpu->cpu_ases) {
>  >  cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
>  > +cpu->cpu_ases_count = cpu->num_ases;
>  >  }
>  >
>  >  newas = >cpu_ases[asidx];
>  > @@ -774,6 +775,34 @@ void cpu_address_space_init(CPUState *cpu, int
>  asidx,
>  >  }
>  >  }
>  >
>  > +void cpu_address_space_destroy(CPUState *cpu, int asidx) {
>  > +CPUAddressSpace *cpuas;
>  > +
>  > +assert(cpu->cpu_ases);
>  > +assert(asidx >= 0 && asidx < cpu->num_ases);
>  > +/* KVM cannot currently support multiple address spaces. */
>  > +assert(asidx == 0 || !kvm_enabled());
>  > +
>  > +cpuas = >cpu_ases[asidx];
>  > +if (tcg_enabled()) {
>  > +memory_listener_unregister(>tcg_as_listener);
>  > +}
>  > +
>  > +address_space_destroy(cpuas->as);
>  > +g_free_rcu(cpuas->as, rcu);
>  > +
>  > +if (asidx == 0) {
>  > +/* reset the convenience alias for address space 0 */
>  > +cpu->as = NULL;
>  > +}
>  > +
>  > +if (--cpu->cpu_ases_count == 0) {
>  > +g_free(cpu->cpu_ases);
>  > +cpu->cpu_ases = NULL;
>  > +}
>  > +}
>  
>  When do we need to destroy a single address space in this way that means
>  we need to keep a count of how many ASes the CPU currently has? The
>  commit message talks about the case when we unrealize the whole CPU
>  object, but in that situation you can just throw away all the ASes at once 
> (eg
>  by calling some
>  cpu_destroy_address_spaces() function from cpu_common_unrealizefn()).


Yes, maybe, we can destroy all at once from common leg as well. I'd prefer this
to be done from the arch specific function for ARM to maintain the clarity &
symmetry of initialization and un-initialization legs.  For now, all of these 
address
space destruction is happening in context to the arm_cpu_unrealizefn().

It’s a kind of trade-off between little more code and clarity but I'm open to
further suggestions.


>  
>  Also, if we're leaking stuff here by failing to destroy it, is that a 
> problem for
>  existing CPU types like x86 that we can already hotplug?

No we are not. We are taking care of these in the ARM arch specific legs
within functions arm_cpu_(un)realizefn(). 

https://lore.kernel.org/all/20230926103654.34424-1-salil.me...@huawei.com/

Above change now would be part of Arch specific patch-set RFC V3 being prepared.


Thanks
Salil.



RE: [PATCH V8 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-03 Thread Salil Mehta via
Hi Vishnu,

>  From: Vishnu Pajjuri  
>  Sent: Thursday, April 4, 2024 3:01 PM
>  To: Salil Mehta ; qemu-devel@nongnu.org; 
> qemu-...@nongnu.org
>  
>  Hi Salil,
>>  On 12-03-2024 07:29, Salil Mehta wrote:
>>  ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
>>  _CRS object of GED to intimate OSPM about an event. Later then 
>> demultiplexes the
>>  notified event by evaluating ACPI _EVT method to know the type of event. Use
>>  ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.
>>  
>>  ACPI CPU hotplug related initialization should only happen if 
>> ACPI_CPU_HOTPLUG
>>  support has been enabled for particular architecture. Add 
>> cpu_hotplug_hw_init()
>>  stub to avoid compilation break.
>>  
>>  Co-developed-by: Keqian Zhu mailto:zhukeqi...@huawei.com
>>  Signed-off-by: Keqian Zhu mailto:zhukeqi...@huawei.com
>>  Signed-off-by: Salil Mehta mailto:salil.me...@huawei.com
>>  Reviewed-by: Jonathan Cameron mailto:jonathan.came...@huawei.com
>>  Reviewed-by: Gavin Shan mailto:gs...@redhat.com
>>  Reviewed-by: David Hildenbrand mailto:da...@redhat.com
>>  Reviewed-by: Shaoqin Huang mailto:shahu...@redhat.com
>>  Tested-by: Vishnu Pajjuri mailto:vis...@os.amperecomputing.com
>>  Tested-by: Xianglai Li mailto:lixiang...@loongson.cn
>>  Tested-by: Miguel Luis mailto:miguel.l...@oracle.com
>>  ---
>>   hw/acpi/acpi-cpu-hotplug-stub.c>|  6 ++
>>   hw/acpi/generic_event_device.c> | 17 +
>>   include/hw/acpi/generic_event_device.h |  4 
>>   3 files changed, 27 insertions(+)
>>  
>>  diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c 
>> b/hw/acpi/acpi-cpu-hotplug-stub.c
>>  index 3fc4b14c26..c6c61bb9cd 100644
>>  --- a/hw/acpi/acpi-cpu-hotplug-stub.c
>>  +++ b/hw/acpi/acpi-cpu-hotplug-stub.c
>>  @@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
>> Object *owner,
>>   return;
>>   }
>>   
>>  +void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
>>  + CPUHotplugState *state, hwaddr base_addr)
>>  +{
>>  +return;
>>  +}
>>  +
>>   void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
>>   {
>>   return;
>>  diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
>>  index 2d6e91b124..35a71505a5 100644
>>  --- a/hw/acpi/generic_event_device.c
>>  +++ b/hw/acpi/generic_event_device.c
>>  @@ -12,6 +12,7 @@
>>   #include "qemu/osdep.h"
>>   #include "qapi/error.h"
>>   #include "hw/acpi/acpi.h"
>>  +#include "hw/acpi/cpu.h"
>>   #include "hw/acpi/generic_event_device.h"
>>   #include "hw/irq.h"
>>   #include "hw/mem/pc-dimm.h"
>>  @@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
>>   ACPI_GED_MEM_HOTPLUG_EVT,
>>   ACPI_GED_PWR_DOWN_EVT,
>>   ACPI_GED_NVDIMM_HOTPLUG_EVT,
>>  +ACPI_GED_CPU_HOTPLUG_EVT,
>>   };
>>   
>>   /*
>>  @@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
>> *hotplug_dev,
>>   } else {
>>   acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
>>   }
>>  +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>  +acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
>>   } else {
>>   error_setg(errp, "virt: device plug request for unsupported device"
>>  " type: %s", object_get_typename(OBJECT(dev)));
>>  @@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
>> *hotplug_dev,
>>   if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>>  !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
>>  > acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, 
>> errp);
>>  +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>  +acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
>>   } else {
>>   error_setg(errp, "acpi: device unplug request for unsupported device"
>>  " type: %s", object_get_typename(OBJECT(dev)));
>>  @@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler 
>> *hotplug_dev,
>>   
>>   if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>   acpi_memory_unplug_cb(>memhp_state, dev, errp);
>>  +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>  +acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
>>   } else {
>>   error_setg(errp, "acpi: device unplug for unsupported device"
>>  " type: %s", object_get_typename(OBJECT(dev)));
>>  @@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
>> ACPIOSTInfoList ***list)
>>   AcpiGedState *s = ACPI_GED(adev);
>>   
>>   acpi_memory_ospm_status(>memhp_state, list);
>>  +acpi_cpu_ospm_status(>cpuhp_state, list);
>>   }
>>   
>>   static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
>>  @@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
>> AcpiEventStatusBits ev)
>>   sel = ACPI_GED_PWR_DOWN_EVT;
>>   } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
>>   sel = 

RE: [PATCH V8 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-05-03 Thread Salil Mehta via
Hello,

Sorry, I missed this earlier.

>  From: Zhao Liu 
>  Sent: Wednesday, March 13, 2024 6:14 AM
>  To: Salil Mehta 
>  
>  Hi Salil,
>  
>  It seems my comment [1] in v7 was missed, but I still hit the same issue. Pls
>  let me paste the previous comment here again.
>  
>  [1]: https://lore.kernel.org/qemu-devel/zxcqp32ggifvu...@intel.com/

Yes, I have this in my mind. 

>  
>  [snip]
>  
>  > @@ -400,6 +411,12 @@ static void acpi_ged_initfn(Object *obj)
>  >  memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
>  >TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
>  >  sysbus_init_mmio(sbd, _st->regs);
>  > +
>  > +memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp
>  container",
>  > +   ACPI_CPU_HOTPLUG_REG_LEN);
>  > +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
>  > +cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
>  > +>cpuhp_state, 0);
>  >  }
>  >
>  
>  I find this cpu_hotplug_hw_init() can still cause qtest errors (for v8) on 
> x86
>  platforms as you mentioned in v6:
>  https://lore.kernel.org/qemu-devel/15e70616-6abb-63a4-17d0-
>  820f4a254...@opnsrc.net/T/#m108f102b2fe92b7dd7218f2f942f7b233a9d6a
>  f3
>  
>  IIUC, microvm machine has its own 'possible_cpus_arch_ids' and that is
>  inherited from its parent x86 machine.
>  
>  The above error is because device-introspect-test sets the none-machine:
>  
>  # starting QEMU: exec ./qemu-system-i386 -qtest unix:/tmp/qtest-
>  3094820.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-
>  3094820.qmp,id=char0 -mon chardev=char0,mode=control -display none -
>  audio none -nodefaults -machine none -accel qtest
>  
>  So what about just checking mc->possible_cpu_arch_ids instead of an
>  assert in cpu_hotplug_hw_init()?
>  
>  diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index
>  4b24a2500361..303f1f1f57bc 100644
>  --- a/hw/acpi/cpu.c
>  +++ b/hw/acpi/cpu.c
>  @@ -221,7 +221,10 @@ void cpu_hotplug_hw_init(MemoryRegion *as,
>  Object *owner,
>   const CPUArchIdList *id_list;
>   int i;
>  
>  -assert(mc->possible_cpu_arch_ids);
>  +if (!mc->possible_cpu_arch_ids) {
>  +return;
>  +}
>  +


Yes, we can do this with some debug print or trace maybe.


>   id_list = mc->possible_cpu_arch_ids(machine);
>   state->dev_count = id_list->len;
>   state->devs = g_new0(typeof(*state->devs), state->dev_count);
>  
>  This check seems to be acceptable in the general code path? Not all
>  machines have possible_cpu_arch_ids, after all.

True. BTW, have you tested this with Qtest?

Thanks
Salil.





RE: [PATCH V8 7/8] gdbstub: Add helper function to unregister GDB register space

2024-05-03 Thread Salil Mehta via
Hi Vishnu,
Sorry for the delay in reply. Still catching up.

>  From: Vishnu Pajjuri  
>  Sent: Thursday, April 4, 2024 3:02 PM
>  To: Salil Mehta ; qemu-devel@nongnu.org; 
> qemu-...@nongnu.org
>  
>  Hi Salil,
>  On 12-03-2024 07:29, Salil Mehta wrote:
>>  Add common function to help unregister the GDB register space. This shall be
>>  done in context to the CPU unrealization.
>>  
>>  Signed-off-by: Salil Mehta mailto:salil.me...@huawei.com
>>  Tested-by: Vishnu Pajjuri mailto:vis...@os.amperecomputing.com
>>  Reviewed-by: Gavin Shan mailto:gs...@redhat.com
>>  Tested-by: Xianglai Li mailto:lixiang...@loongson.cn
>>  Tested-by: Miguel Luis mailto:miguel.l...@oracle.com
>>  Reviewed-by: Shaoqin Huang mailto:shahu...@redhat.com
>>  ---
>>   gdbstub/gdbstub.c>  | 12 
>>   include/exec/gdbstub.h |  6 ++
>>   2 files changed, 18 insertions(+)
>>  
>>  diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
>>  index 17efcae0d0..a8449dc309 100644
>>  --- a/gdbstub/gdbstub.c
>>  +++ b/gdbstub/gdbstub.c
>>  @@ -615,6 +615,18 @@ void gdb_register_coprocessor(CPUState *cpu,
>>   }
>>   }
>>   
>>  +void gdb_unregister_coprocessor_all(CPUState *cpu)
>>  +{
>>  +/*
>>  + * Safe to nuke everything. GDBRegisterState::xml is static const char 
>> so
>>  + * it won't be freed
>>  + */
>>  +g_array_free(cpu->gdb_regs, true);
>>  +
>>  +cpu->gdb_regs = NULL;
>>  +cpu->gdb_num_g_regs = 0;
>  Likewise, you may need to set gdb_num_regs to zero as well.


Sure, thanks.


>>  +}
>>  +
>>   static void gdb_process_breakpoint_remove_all(GDBProcess *p)
>>   {
>>   CPUState *cpu = gdb_get_first_cpu_in_process(p);
>>  diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
>>  index eb14b91139..249d4d4bc8 100644
>>  --- a/include/exec/gdbstub.h
>>  +++ b/include/exec/gdbstub.h
>>  @@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
>>  >  >  >  >  >   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
>>  >  >  >  >  >   const GDBFeature *feature, int g_pos);
>>   
>>  +/**
>>  + * gdb_unregister_coprocessor_all() - unregisters supplemental set of 
>> registers
>>  + * @cpu - the CPU associated with registers
>>  + */
>>  +void gdb_unregister_coprocessor_all(CPUState *cpu);
>>  +
>>   /**
>>* gdbserver_start: start the gdb server
>>* @port_or_device: connection spec for gdb
>>  Otherwise, Looks good to me.  Feel free to add
>>  Reviewed-by: "Vishnu Pajjuri" mailto:vis...@os.amperecomputing.com

Thanks
Salil.


>>  Regards,
>>  -Vishnu



RE: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-03 Thread Salil Mehta via
Hello,

Just replied to your other thread just now. Sorry catching everything late.

Thanks

>  From: Harsh Prateek Bora 
>  Sent: Tuesday, April 23, 2024 7:44 AM
>  
>  + Nick
>  
>  Hi Salil,
>  I have posted a patch [1] for ppc which based on this refactoring patch.
>  I see there were some comments from Vishnu on this patch.
>  Are we expecting any further updates on this patch before merge?


Yes, few of them and I'm working towards it. I've received most of the reviews
and SOBs last year itself. There are few minor comments to be addressed before
I can float V9 version of this patch-set.

I'm planning to push that for review in 2 weeks of time along with  RFC V3 of
the architecture specific code.


Thanks
Salil.


>  
>  Thanks
>  Harsh
>  
>  [1]
>  https://lore.kernel.org/qemu-devel/a0f9b2fc-4c8a-4c37-bc36-
>  26bbaa627...@linux.ibm.com/T/#u
>  
>  On 3/22/24 13:45, Harsh Prateek Bora wrote:
>  > + Vaibhav, Shiva
>  >
>  > Hi Salil,
>  >
>  > I came across your patch while trying to solve a related problem on
>  > spapr. One query below ..
>  >
>  > On 3/12/24 07:29, Salil Mehta via wrote:
>  >> KVM vCPU creation is done once during the vCPU realization when
>  Qemu
>  >> vCPU thread is spawned. This is common to all the architectures as of
>  >> now.
>  >>
>  >> Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  >> but the corresponding KVM vCPU object in the Host KVM is not
>  >> destroyed as KVM doesn't support vCPU removal. Therefore, its
>  >> representative KVM vCPU object/context in Qemu is parked.
>  >>
>  >> Refactor architecture common logic so that some APIs could be reused
>  >> by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  >> Update new/old APIs with trace events instead of DPRINTF. No
>  >> functional change is intended here.
>  >>
>  >> Signed-off-by: Salil Mehta 
>  >> Reviewed-by: Gavin Shan 
>  >> Tested-by: Vishnu Pajjuri 
>  >> Reviewed-by: Jonathan Cameron 
>  >> Tested-by: Xianglai Li 
>  >> Tested-by: Miguel Luis 
>  >> Reviewed-by: Shaoqin Huang 
>  >> ---
>  >>   accel/kvm/kvm-all.c    | 64
>  >> --
>  >>   accel/kvm/trace-events |  5 +++-
>  >>   include/sysemu/kvm.h   | 16 +++
>  >>   3 files changed, 69 insertions(+), 16 deletions(-)
>  >>
>  >> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  >> a8cecd040e..3bc3207bda 100644
>  >> --- a/accel/kvm/kvm-all.c
>  >> +++ b/accel/kvm/kvm-all.c
>  >> @@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
>  >>   #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >>   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  >> +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  >>   static inline void kvm_resample_fd_remove(int gsi)
>  >>   {
>  >> @@ -314,14 +315,53 @@ err:
>  >>   return ret;
>  >>   }
>  >> +void kvm_park_vcpu(CPUState *cpu)
>  >> +{
>  >> +    struct KVMParkedVcpu *vcpu;
>  >> +
>  >> +    trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  >> +
>  >> +    vcpu = g_malloc0(sizeof(*vcpu));
>  >> +    vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  >> +    vcpu->kvm_fd = cpu->kvm_fd;
>  >> +    QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
>  }
>  >> +
>  >> +int kvm_create_vcpu(CPUState *cpu)
>  >> +{
>  >> +    unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  >> +    KVMState *s = kvm_state;
>  >> +    int kvm_fd;
>  >> +
>  >> +    trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  >> +
>  >> +    /* check if the KVM vCPU already exist but is parked */
>  >> +    kvm_fd = kvm_get_vcpu(s, vcpu_id);
>  >> +    if (kvm_fd < 0) {
>  >> +    /* vCPU not parked: create a new KVM vCPU */
>  >> +    kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  >> +    if (kvm_fd < 0) {
>  >> +    error_report("KVM_CREATE_VCPU IOCTL failed for vCPU
>  >> +%lu",
>  >> vcpu_id);
>  >> +    return kvm_fd;
>  >> +    }
>  >> +    }
>  >> +
>  >> +    cpu->kvm_fd = kvm_fd;
>  >> +    cpu->kvm_state = s;
>  >> +    cpu->vcpu_dirty = true;
>  >> +    cpu->dirty_pages = 0;
>  >> +    cpu->thr

RE: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-05-03 Thread Salil Mehta via
Hi Harsh,

Sorry for the delay in my reply. I've been off the grid for some time so missed 
this
earlier mail. Please find my reply below to you query.

Thanks

>  From: Harsh Prateek Bora 
>  Sent: Friday, March 22, 2024 8:15 AM
>  
>  + Vaibhav, Shiva
>  
>  Hi Salil,
>  
>  I came across your patch while trying to solve a related problem on spapr.
>  One query below ..
>  
>  On 3/12/24 07:29, Salil Mehta via wrote:
>  > KVM vCPU creation is done once during the vCPU realization when Qemu
>  > vCPU thread is spawned. This is common to all the architectures as of now.
>  >
>  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  > vCPU object/context in Qemu is parked.
>  >
>  > Refactor architecture common logic so that some APIs could be reused
>  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  > Update new/old APIs with trace events instead of DPRINTF. No functional
>  change is intended here.
>  >
>  > Signed-off-by: Salil Mehta 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Jonathan Cameron 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  > ---
>  >   accel/kvm/kvm-all.c| 64 --
>  
>  >   accel/kvm/trace-events |  5 +++-
>  >   include/sysemu/kvm.h   | 16 +++
>  >   3 files changed, 69 insertions(+), 16 deletions(-)
>  >
>  > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  > a8cecd040e..3bc3207bda 100644
>  > --- a/accel/kvm/kvm-all.c
>  > +++ b/accel/kvm/kvm-all.c
>  > @@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
>  >   #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >
>  >   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  > +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  >
>  >   static inline void kvm_resample_fd_remove(int gsi)
>  >   {
>  > @@ -314,14 +315,53 @@ err:
>  >   return ret;
>  >   }
>  >
>  > +void kvm_park_vcpu(CPUState *cpu)
>  > +{
>  > +struct KVMParkedVcpu *vcpu;
>  > +
>  > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +vcpu = g_malloc0(sizeof(*vcpu));
>  > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +vcpu->kvm_fd = cpu->kvm_fd;
>  > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  > +
>  > +int kvm_create_vcpu(CPUState *cpu)
>  > +{
>  > +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +KVMState *s = kvm_state;
>  > +int kvm_fd;
>  > +
>  > +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +/* check if the KVM vCPU already exist but is parked */
>  > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +/* vCPU not parked: create a new KVM vCPU */
>  > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu",
>  vcpu_id);
>  > +return kvm_fd;
>  > +}
>  > +}
>  > +
>  > +cpu->kvm_fd = kvm_fd;
>  > +cpu->kvm_state = s;
>  > +cpu->vcpu_dirty = true;
>  > +cpu->dirty_pages = 0;
>  > +cpu->throttle_us_per_full = 0;
>  > +
>  > +return 0;
>  > +}
>  > +
>  >   static int do_kvm_destroy_vcpu(CPUState *cpu)
>  >   {
>  >   KVMState *s = kvm_state;
>  >   long mmap_size;
>  > -struct KVMParkedVcpu *vcpu = NULL;
>  >   int ret = 0;
>  >
>  > -trace_kvm_destroy_vcpu();
>  > +trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  >
>  >   ret = kvm_arch_destroy_vcpu(cpu);
>  >   if (ret < 0) {
>  > @@ -347,10 +387,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
>  >   }
>  >   }
>  >
>  > -vcpu = g_malloc0(sizeof(*vcpu));
>  > -vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > -vcpu->kvm_fd = cpu->kvm_fd;
>  > -QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
>  > +kvm_park_vcpu(cpu);
>  >   err:
>  >   return ret;
>  >   }
>  > @@ -371,6 +408,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned

RE: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-03 Thread Salil Mehta via
Hi Vishnu,

>  From: Vishnu Pajjuri  
>  Sent: Thursday, April 4, 2024 3:00 PM
>  Subject: Re: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU 
> {creation,parking} code
>  
>  Hi Salil,
>>  On 12-03-2024 07:29, Salil Mehta wrote:
>>  KVM vCPU creation is done once during the vCPU realization when Qemu vCPU 
>> thread
>>  is spawned. This is common to all the architectures as of now.
>>  
>>  Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
>>  corresponding KVM vCPU object in the Host KVM is not destroyed as KVM 
>> doesn't
>>  support vCPU removal. Therefore, its representative KVM vCPU object/context 
>> in
>>  Qemu is parked.
>>  
>>  Refactor architecture common logic so that some APIs could be reused by vCPU
>>  Hotplug code of some architectures likes ARM, Loongson etc. Update new/old 
>> APIs
>>  with trace events instead of DPRINTF. No functional change is intended here.
>>  
>>  Signed-off-by: Salil Mehta mailto:salil.me...@huawei.com
>>  Reviewed-by: Gavin Shan mailto:gs...@redhat.com
>>  Tested-by: Vishnu Pajjuri mailto:vis...@os.amperecomputing.com
>>  Reviewed-by: Jonathan Cameron mailto:jonathan.came...@huawei.com
>>  Tested-by: Xianglai Li mailto:lixiang...@loongson.cn
>>  Tested-by: Miguel Luis mailto:miguel.l...@oracle.com
>>  Reviewed-by: Shaoqin Huang mailto:shahu...@redhat.com
>>  ---
>>   accel/kvm/kvm-all.c| 64 --
>>   accel/kvm/trace-events |  5 +++-
>>   include/sysemu/kvm.h   | 16 +++
>>   3 files changed, 69 insertions(+), 16 deletions(-)
>>  
>>  diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
>>  index a8cecd040e..3bc3207bda 100644
>>  --- a/accel/kvm/kvm-all.c
>>  +++ b/accel/kvm/kvm-all.c
>>  @@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
>>   #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>>   
>>   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>>  +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>>   
>>   static inline void kvm_resample_fd_remove(int gsi)
>>   {
>>  @@ -314,14 +315,53 @@ err:
>>  return ret;
>>   }
>>   
>>  +void kvm_park_vcpu(CPUState *cpu)
>>  +{
>>  +struct KVMParkedVcpu *vcpu;
>>  +
>>  +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  It's good if we add kvm_fd to trace.
>  It will be useful to cross verify kvm_get_vcpu()'s kvm_fd with parked vcpu.


Agreed. But this is currently called in context to create and destroy vCPU
where the trace already exists with the info you are seeking. Having
trace here might duplicate the info and end up increasing the noise.

Let me know if you think otherwise or have something else to add.

Thanks

 
>>  +
>>  +vcpu = g_malloc0(sizeof(*vcpu));
>>  +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>>  +vcpu->kvm_fd = cpu->kvm_fd;
>>  +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
>>  +}
>>  +
>>  +int kvm_create_vcpu(CPUState *cpu)
>>  +{
>>  +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>>  +KVMState *s = kvm_state;
>>  +int kvm_fd;
>>  +
>>  +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  vcpu_id can be used instead of kvm_arch_vcpu_id(cpu).


KVM arch VCPU Id ensures that ID being traced is meaningful for that
architecture. The way CPU ID gets calculated in on different architectures
could be different. Hence, its value might be quite different.

  
>>  +
>>  +/* check if the KVM vCPU already exist but is parked */
>>  +kvm_fd = kvm_get_vcpu(s, vcpu_id);
>>  +if (kvm_fd < 0) {
>>  +>   /* vCPU not parked: create a new KVM vCPU */
>>  +>   kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>>  +>   if (kvm_fd < 0) {
>>  +>   error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
>>  +>   return kvm_fd;
>>  +>   }
>>  +}
>>  +
>>  +cpu->kvm_fd = kvm_fd;
>>  +cpu->kvm_state = s;
>>  +cpu->vcpu_dirty = true;
>>  +cpu->dirty_pages = 0;
>>  +cpu->throttle_us_per_full = 0;
>>  +
>>  +return 0;
>>  +}
>>  +
>>   static int do_kvm_destroy_vcpu(CPUState *cpu)
>>   {
>>   KVMState *s = kvm_state;
>>   long mmap_size;
>>  -struct KVMParkedVcpu *vcpu = NULL;
>>   int ret = 0;
>>   
>>  -trace_kvm_destroy_vcpu();
>>  +trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>>   
>>   ret = kvm_arch_destroy_vcpu(cpu);
>>   if (ret < 0) {
>>  @@ -347,10 +387,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
>>  >}
>>   }
>>   
>>  -vcpu = g_malloc0(sizeof(*vcpu));
>>  -vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>>  -vcpu->kvm_fd = cpu->kvm_fd;
>>  -QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
>>  +kvm_park_vcpu(cpu);
>>   err:
>>   return ret;
>>   }
>>  @@ -371,6 +408,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long 
>> vcpu_id)
>>  >if (cpu->vcpu_id == vcpu_id) {
>>  >int kvm_fd;
>>   
>>  +>   trace_kvm_get_vcpu(vcpu_id);
>  It's good if we add kvm_fd to trace.
>  

RE: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation,parking} code

2024-05-03 Thread Salil Mehta via
Hi Philippe,

>  From: Philippe Mathieu-Daudé 
>  Sent: Friday, May 3, 2024 10:40 AM
>  Subject: Re: [PATCH V8 1/8] accel/kvm: Extract common KVM vCPU
>  {creation,parking} code
>  
>  Hi Salil,
>  
>  On 12/3/24 02:59, Salil Mehta wrote:
>  > KVM vCPU creation is done once during the vCPU realization when Qemu
>  > vCPU thread is spawned. This is common to all the architectures as of now.
>  >
>  > Hot-unplug of vCPU results in destruction of the vCPU object in QOM
>  > but the corresponding KVM vCPU object in the Host KVM is not destroyed
>  > as KVM doesn't support vCPU removal. Therefore, its representative KVM
>  > vCPU object/context in Qemu is parked.
>  >
>  > Refactor architecture common logic so that some APIs could be reused
>  > by vCPU Hotplug code of some architectures likes ARM, Loongson etc.
>  > Update new/old APIs with trace events instead of DPRINTF. No functional
>  change is intended here.
>  >
>  > Signed-off-by: Salil Mehta 
>  > Reviewed-by: Gavin Shan 
>  > Tested-by: Vishnu Pajjuri 
>  > Reviewed-by: Jonathan Cameron 
>  > Tested-by: Xianglai Li 
>  > Tested-by: Miguel Luis 
>  > Reviewed-by: Shaoqin Huang 
>  > ---
>  >   accel/kvm/kvm-all.c| 64 --
>  
>  >   accel/kvm/trace-events |  5 +++-
>  >   include/sysemu/kvm.h   | 16 +++
>  >   3 files changed, 69 insertions(+), 16 deletions(-)
>  >
>  > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
>  > a8cecd040e..3bc3207bda 100644
>  > --- a/accel/kvm/kvm-all.c
>  > +++ b/accel/kvm/kvm-all.c
>  > @@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
>  >   #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
>  >
>  >   static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
>  > +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
>  >
>  >   static inline void kvm_resample_fd_remove(int gsi)
>  >   {
>  > @@ -314,14 +315,53 @@ err:
>  >   return ret;
>  >   }
>  >
>  > +void kvm_park_vcpu(CPUState *cpu)
>  > +{
>  > +struct KVMParkedVcpu *vcpu;
>  > +
>  > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +vcpu = g_malloc0(sizeof(*vcpu));
>  > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +vcpu->kvm_fd = cpu->kvm_fd;
>  > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node); }
>  > +
>  > +int kvm_create_vcpu(CPUState *cpu)
>  > +{
>  > +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
>  > +KVMState *s = kvm_state;
>  > +int kvm_fd;
>  > +
>  > +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
>  > +
>  > +/* check if the KVM vCPU already exist but is parked */
>  > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +/* vCPU not parked: create a new KVM vCPU */
>  > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
>  > +if (kvm_fd < 0) {
>  > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu",  
> vcpu_id);
>  > +return kvm_fd;
>  > +}
>  > +}
>  > +
>  > +cpu->kvm_fd = kvm_fd;
>  > +cpu->kvm_state = s;
>  > +cpu->vcpu_dirty = true;
>  > +cpu->dirty_pages = 0;
>  > +cpu->throttle_us_per_full = 0;
>  > +
>  > +return 0;
>  > +}
>  
>  This seems generic enough to be implemented for all accelerators.
>  
>  See AccelOpsClass in include/sysemu/accel-ops.h.
>  
>  That said, can be done later on top.

Let me understand correctly. Are you suggesting to implement above even for
HVF, TCG, QTEST etc?

Thanks
Salil.






[PATCH V8 6/8] physmem: Add helper function to destroy CPU AddressSpace

2024-03-11 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6346df17ce..a427d80340 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -123,6 +123,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index ec14f74ce5..e975b8085f 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -493,6 +493,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index 6e9ed97597..61b32ac4f2 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -761,6 +761,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -774,6 +775,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V8 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2024-03-11 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V8 7/8] gdbstub: Add helper function to unregister GDB register space

2024-03-11 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 gdbstub/gdbstub.c  | 12 
 include/exec/gdbstub.h |  6 ++
 2 files changed, 18 insertions(+)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 17efcae0d0..a8449dc309 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -615,6 +615,18 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index eb14b91139..249d4d4bc8 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -49,6 +49,12 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
-- 
2.34.1




[PATCH V8 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2024-03-11 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 69aaa563db..bde5a42a0b 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -323,7 +323,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 35a71505a5..58c7882555 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V8 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2024-03-11 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index bde5a42a0b..b5fb2075d0 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -339,9 +339,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -366,13 +367,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -696,9 +703,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 15242b9096..f0cdfaf9aa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1536,7 +1536,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9ef59..48cded697c 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -61,9 +61,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 

[PATCH V8 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2024-03-11 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 3 files changed, 27 insertions(+)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124..35a71505a5 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } else {
 /* Unknown event. Return without generating interrupt. */
 warn_report("GED: Unsupported event %d. No irq injected", ev);
@@ -400,6 +411,12 @@ static void acpi_ged_initfn(Object *obj)
 memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
   TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
 sysbus_init_mmio(sbd, _st->regs);
+
+memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp container",
+   ACPI_CPU_HOTPLUG_REG_LEN);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
+cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
+>cpuhp_state, 0);
 }
 
 static 

[PATCH V8 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2024-03-11 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 2d81c1e790..69aaa563db 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V8 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2024-03-11 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events instead of DPRINTF. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  5 +++-
 include/sysemu/kvm.h   | 16 +++
 3 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index a8cecd040e..3bc3207bda 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -126,6 +126,7 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
 
 static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -314,14 +315,53 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_get_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-trace_kvm_destroy_vcpu();
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -347,10 +387,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -371,6 +408,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 if (cpu->vcpu_id == vcpu_id) {
 int kvm_fd;
 
+trace_kvm_get_vcpu(vcpu_id);
+
 QLIST_REMOVE(cpu, node);
 kvm_fd = cpu->kvm_fd;
 g_free(cpu);
@@ -378,7 +417,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 }
 }
 
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+return -ENOENT;
 }
 
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -389,19 +428,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index a25902597b..5558cff0dc 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -9,6 +9,10 @@ kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 
0x%x, arg %p"
 kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve 
ONEREG %" PRIu64 " from KVM: %s"
 kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set 
ONEREG %" PRIu64 " to KVM: %s"
 

[PATCH V8 0/8] Add architecture agnostic code to support vCPU Hotplug

2024-03-11 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v2.common.v8


Revision History:

Patch-set V7 -> V8

1. Rebased and Fixed the conflicts

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/

Patch-set V1 -> V2
1. Addressed Alex Bennée's comments
   - Refactored the kvm_create_vcpu logic to get rid of goto
   - Added the docs for kvm_{create,park}_vcpu prototypes
   - Splitted the gdbstub and AddressSpace destruction change into separate 
patches
   - Added Reviewed-by tags for patches {2,10}
Link: 
https://lore.kernel.org/qemu-devel/20230929124304.13672-1-salil.me...@huawei.com/

References:

[1] 
https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/
[2] https://lore.kernel.org/all/20230913163823.7880-1-james.mo...@arm.com/
[3] 
https://lore.kernel.org/qemu-devel/cover.1695697701.git.lixiang...@loongson.cn/



Salil Mehta (8):
  accel/kvm: Extract common KVM vCPU {creation,parking} code
  hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
  hw/acpi: Update ACPI GED framework to support vCPU Hotplug
  hw/acpi: Update GED _EVT method AML with CPU scan
  hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
  physmem: Add helper function to destroy CPU AddressSpace
  gdbstub: Add helper function to unregister GDB register space
  docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  5 +-
 docs/specs/acpi_hw_reduced_hotplug.rst |  3 +-
 gdbstub/gdbstub.c  | 12 +
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 +++
 hw/acpi/cpu.c  | 27 +++
 hw/acpi/generic_event_device.c | 21 +
 hw/i386/acpi-build.c   |  3 +-
 include/exec/cpu-common.h  |  8 
 include/exec/gdbstub.h |  6 +++
 include/hw/acpi/cpu.h  |  5 +-
 

[PATCH V7 7/8] gdbstub: Add helper function to unregister GDB register space

2023-11-13 Thread Salil Mehta via
Add common function to help unregister the GDB register space. This shall be
done in context to the CPU unrealization.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 gdbstub/gdbstub.c  | 12 
 include/exec/gdbstub.h |  5 +
 2 files changed, 17 insertions(+)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b1532118d1..7bd6d45857 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -498,6 +498,18 @@ void gdb_register_coprocessor(CPUState *cpu,
 }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+/*
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
+ * it won't be freed
+ */
+g_array_free(cpu->gdb_regs, true);
+
+cpu->gdb_regs = NULL;
+cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
 CPUState *cpu = gdb_get_first_cpu_in_process(p);
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 1a01c35f8e..3744257ed3 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -32,6 +32,11 @@ typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t 
*buf, int reg);
 void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   int num_regs, const char *xml, int g_pos);
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
 
 /**
  * gdbserver_start: start the gdb server
-- 
2.34.1




[PATCH V7 8/8] docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

2023-11-13 Thread Salil Mehta via
GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug
and non-hotplug events like system power down event. Each of these can be
selected using a bit in the 32 bit GED IO interface. A bit has been reserved for
the CPU hotplug event.

Signed-off-by: Salil Mehta 
---
 docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst 
b/docs/specs/acpi_hw_reduced_hotplug.rst
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
2: NVDIMM hotplug event
-3-31: Reserved
+   3: CPU hotplug event
+4-31: Reserved
 
 **write_access:**
 
-- 
2.34.1




[PATCH V7 6/8] physmem: Add helper function to destroy CPU AddressSpace

2023-11-13 Thread Salil Mehta via
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
involves destruction of the CPU AddressSpace. Add common function to help
destroy the CPU AddressSpace.

Signed-off-by: Salil Mehta 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Gavin Shan 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 include/exec/cpu-common.h |  8 
 include/hw/core/cpu.h |  1 +
 system/physmem.c  | 29 +
 3 files changed, 38 insertions(+)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 605b160a7e..a930e49e02 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -127,6 +127,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
 const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
 hwaddr len, bool is_write);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 3968369554..708b6b48de 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -496,6 +496,7 @@ struct CPUState {
 QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
 CPUAddressSpace *cpu_ases;
+int cpu_ases_count;
 int num_ases;
 AddressSpace *as;
 MemoryRegion *memory;
diff --git a/system/physmem.c b/system/physmem.c
index edc3ed8ab9..a16f1d4056 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -761,6 +761,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
 if (!cpu->cpu_ases) {
 cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+cpu->cpu_ases_count = cpu->num_ases;
 }
 
 newas = >cpu_ases[asidx];
@@ -774,6 +775,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+CPUAddressSpace *cpuas;
+
+assert(cpu->cpu_ases);
+assert(asidx >= 0 && asidx < cpu->num_ases);
+/* KVM cannot currently support multiple address spaces. */
+assert(asidx == 0 || !kvm_enabled());
+
+cpuas = >cpu_ases[asidx];
+if (tcg_enabled()) {
+memory_listener_unregister(>tcg_as_listener);
+}
+
+address_space_destroy(cpuas->as);
+g_free_rcu(cpuas->as, rcu);
+
+if (asidx == 0) {
+/* reset the convenience alias for address space 0 */
+cpu->as = NULL;
+}
+
+if (--cpu->cpu_ases_count == 0) {
+g_free(cpu->cpu_ases);
+cpu->cpu_ases = NULL;
+}
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
 /* Return the AddressSpace corresponding to the specified index */
-- 
2.34.1




[PATCH V7 5/8] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2023-11-13 Thread Salil Mehta via
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
resource which describes IO Port address. But on ARM arch CPUs control
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
evaluate to system resource which describes memory-mapped base address. Update
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
update the _CRS object.

On x86, CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event handler to
notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug is based on
ACPI Generic Event Device framework and uses ACPI GED device for the same. Not
all architectures support GPE based CPU Hotplug event handler. Hence, make AML
for GPE.2 event handler conditional.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c | 23 ---
 hw/i386/acpi-build.c  |  3 ++-
 include/hw/acpi/cpu.h |  5 +++--
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index de1f9295dc..5b0eaad1c5 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -339,9 +339,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method)
+const char *event_handler_method,
+AmlRegionSpace rs)
 {
 Aml *ifctx;
 Aml *field;
@@ -366,13 +367,19 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
 crs = aml_resource_template();
-aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+if (rs == AML_SYSTEM_IO) {
+aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
ACPI_CPU_HOTPLUG_REG_LEN));
+} else {
+aml_append(crs, aml_memory32_fixed(base_addr,
+   ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+}
+
 aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
 /* declare CPU hotplug MMIO region with related access fields */
 aml_append(cpu_ctrl_dev,
-aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+aml_operation_region("PRST", rs, aml_int(base_addr),
  ACPI_CPU_HOTPLUG_REG_LEN));
 
 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -696,9 +703,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(sb_scope, cpus_dev);
 aml_append(table, sb_scope);
 
-method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-aml_append(table, method);
+if (event_handler_method) {
+method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
+aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
+aml_append(table, method);
+}
 
 g_free(cphp_res_path);
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 3f2b27cf75..f9f31f9db5 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1550,7 +1550,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
 };
 build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+   pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+   AML_SYSTEM_IO);
 }
 
 if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index bc901660fb..b521a4e0de 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -60,9 +60,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const 
CPUArchIdList *apic_ids,
   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
 const char *res_root,
-const char *event_handler_method);
+const char *event_handler_method,
+AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 

[PATCH V7 4/8] hw/acpi: Update GED _EVT method AML with CPU scan

2023-11-13 Thread Salil Mehta via
OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually
results in start of the CPU scan. Scan figures out the CPU and the kind of
event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT
method with the call to \\_SB.CPUS.CSCN

Also, macro CPU_SCAN_METHOD might be referred in other places like during GED
intialization so it makes sense to have its definition placed in some common
header file like cpu_hotplug.h. But doing this can cause compilation break
because of the conflicting macro definitions present in cpu.c and cpu_hotplug.c
and because both these files get compiled due to historic reasons of x86 world
i.e. decision to use legacy(GPE.2)/modern(GED) CPU hotplug interface happens
during runtime [1]. To mitigate above, for now, declare a new common macro
ACPI_CPU_SCAN_METHOD for CPU scan method instead.
(This needs a separate discussion later on for clean-up)

Reference:
[1] 
https://lore.kernel.org/qemu-devel/1463496205-251412-24-git-send-email-imamm...@redhat.com/

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 hw/acpi/cpu.c  | 2 +-
 hw/acpi/generic_event_device.c | 4 
 include/hw/acpi/cpu_hotplug.h  | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 4b24a25003..de1f9295dc 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -323,7 +323,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPUHP_RES_DEVICE  "PRES"
 #define CPU_LOCK  "CPLK"
 #define CPU_STS_METHOD"CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
+#define CPU_SCAN_METHOD   ACPI_CPU_SCAN_METHOD
 #define CPU_NOTIFY_METHOD "CTFY"
 #define CPU_EJECT_METHOD  "CEJ0"
 #define CPU_OST_METHOD"COST"
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 57b0c2815b..f547b96d74 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -109,6 +109,10 @@ void build_ged_aml(Aml *table, const char *name, 
HotplugHandler *hotplug_dev,
 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
  MEMORY_SLOT_SCAN_METHOD));
 break;
+case ACPI_GED_CPU_HOTPLUG_EVT:
+aml_append(if_ctx, aml_call0(ACPI_CPU_CONTAINER "."
+ ACPI_CPU_SCAN_METHOD));
+break;
 case ACPI_GED_PWR_DOWN_EVT:
 aml_append(if_ctx,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 48b291e45e..ef631750b4 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,8 @@
 #include "hw/acpi/cpu.h"
 
 #define ACPI_CPU_HOTPLUG_REG_LEN 12
+#define ACPI_CPU_SCAN_METHOD "CSCN"
+#define ACPI_CPU_CONTAINER "\\_SB.CPUS"
 
 typedef struct AcpiCpuHotplug {
 Object *device;
-- 
2.34.1




[PATCH V7 3/8] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2023-11-13 Thread Salil Mehta via
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
notified event by evaluating ACPI _EVT method to know the type of event. Use
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
stub to avoid compilation break.

Co-developed-by: Keqian Zhu 
Signed-off-by: Keqian Zhu 
Signed-off-by: Salil Mehta 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 ++
 hw/acpi/generic_event_device.c | 17 +
 include/hw/acpi/generic_event_device.h |  4 
 3 files changed, 27 insertions(+)

diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index 3fc4b14c26..c6c61bb9cd 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+ CPUHotplugState *state, hwaddr base_addr)
+{
+return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
 return;
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index a3d31631fe..57b0c2815b 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -25,6 +26,7 @@ static const uint32_t ged_supported_events[] = {
 ACPI_GED_MEM_HOTPLUG_EVT,
 ACPI_GED_PWR_DOWN_EVT,
 ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ACPI_GED_CPU_HOTPLUG_EVT,
 };
 
 /*
@@ -234,6 +236,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else {
 acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
 }
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -248,6 +252,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
 acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -261,6 +267,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_unplug_cb(>memhp_state, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -272,6 +280,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
ACPIOSTInfoList ***list)
 AcpiGedState *s = ACPI_GED(adev);
 
 acpi_memory_ospm_status(>memhp_state, list);
+acpi_cpu_ospm_status(>cpuhp_state, list);
 }
 
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
@@ -286,6 +295,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 sel = ACPI_GED_PWR_DOWN_EVT;
 } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
 sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+sel = ACPI_GED_CPU_HOTPLUG_EVT;
 } else {
 /* Unknown event. Return without generating interrupt. */
 warn_report("GED: Unsupported event %d. No irq injected", ev);
@@ -400,6 +411,12 @@ static void acpi_ged_initfn(Object *obj)
 memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
   TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
 sysbus_init_mmio(sbd, _st->regs);
+
+memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp container",
+   ACPI_CPU_HOTPLUG_REG_LEN);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
+cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
+>cpuhp_state, 0);
 }
 
 static 

[PATCH V7 2/8] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

2023-11-13 Thread Salil Mehta via
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
appropriate common header file.

Signed-off-by: Salil Mehta 
Reviewed-by: Alex Bennée 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Gavin Shan 
Reviewed-by: David Hildenbrand 
Reviewed-by: Shaoqin Huang 
Tested-by: Vishnu Pajjuri 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
---
 hw/acpi/cpu.c | 2 +-
 include/hw/acpi/cpu_hotplug.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 011d2c6c2d..4b24a25003 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -1,13 +1,13 @@
 #include "qemu/osdep.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/cpu_hotplug.h"
 #include "hw/core/cpu.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-acpi.h"
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932a..48b291e45e 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -19,6 +19,8 @@
 #include "hw/hotplug.h"
 #include "hw/acpi/cpu.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuHotplug {
 Object *device;
 MemoryRegion io;
-- 
2.34.1




[PATCH V7 1/8] accel/kvm: Extract common KVM vCPU {creation, parking} code

2023-11-13 Thread Salil Mehta via
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
support vCPU removal. Therefore, its representative KVM vCPU object/context in
Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
with trace events instead of DPRINTF. No functional change is intended here.

Signed-off-by: Salil Mehta 
Reviewed-by: Gavin Shan 
Tested-by: Vishnu Pajjuri 
Reviewed-by: Jonathan Cameron 
Tested-by: Xianglai Li 
Tested-by: Miguel Luis 
Reviewed-by: Shaoqin Huang 
---
 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  4 +++
 include/sysemu/kvm.h   | 16 +++
 3 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 72e1d1141c..bfa7816aaa 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -137,6 +137,7 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
 
 static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -320,14 +321,53 @@ err:
 return ret;
 }
 
+void kvm_park_vcpu(CPUState *cpu)
+{
+struct KVMParkedVcpu *vcpu;
+
+trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+}
+
+int kvm_create_vcpu(CPUState *cpu)
+{
+unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
+KVMState *s = kvm_state;
+int kvm_fd;
+
+trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
+
+/* check if the KVM vCPU already exist but is parked */
+kvm_fd = kvm_get_vcpu(s, vcpu_id);
+if (kvm_fd < 0) {
+/* vCPU not parked: create a new KVM vCPU */
+kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
+if (kvm_fd < 0) {
+error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
+return kvm_fd;
+}
+}
+
+cpu->kvm_fd = kvm_fd;
+cpu->kvm_state = s;
+cpu->vcpu_dirty = true;
+cpu->dirty_pages = 0;
+cpu->throttle_us_per_full = 0;
+
+return 0;
+}
+
 static int do_kvm_destroy_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
 long mmap_size;
-struct KVMParkedVcpu *vcpu = NULL;
 int ret = 0;
 
-DPRINTF("kvm_destroy_vcpu\n");
+trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
 ret = kvm_arch_destroy_vcpu(cpu);
 if (ret < 0) {
@@ -353,10 +393,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 }
 }
 
-vcpu = g_malloc0(sizeof(*vcpu));
-vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-vcpu->kvm_fd = cpu->kvm_fd;
-QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
+kvm_park_vcpu(cpu);
 err:
 return ret;
 }
@@ -377,6 +414,8 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 if (cpu->vcpu_id == vcpu_id) {
 int kvm_fd;
 
+trace_kvm_get_vcpu(vcpu_id);
+
 QLIST_REMOVE(cpu, node);
 kvm_fd = cpu->kvm_fd;
 g_free(cpu);
@@ -384,7 +423,7 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
 }
 }
 
-return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+return -ENOENT;
 }
 
 int kvm_init_vcpu(CPUState *cpu, Error **errp)
@@ -395,19 +434,14 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 
 trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
 
-ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+ret = kvm_create_vcpu(cpu);
 if (ret < 0) {
-error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed 
(%lu)",
+error_setg_errno(errp, -ret,
+ "kvm_init_vcpu: kvm_create_vcpu failed (%lu)",
  kvm_arch_vcpu_id(cpu));
 goto err;
 }
 
-cpu->kvm_fd = ret;
-cpu->kvm_state = s;
-cpu->vcpu_dirty = true;
-cpu->dirty_pages = 0;
-cpu->throttle_us_per_full = 0;
-
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
 ret = mmap_size;
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index 399aaeb0ec..cdd0c95c09 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -9,6 +9,10 @@ kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 
0x%x, arg %p"
 kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve 
ONEREG %" PRIu64 " from KVM: %s"
 kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set 
ONEREG %" PRIu64 " to KVM: %s"
 

[PATCH V7 0/8] Add architecture agnostic code to support vCPU Hotplug

2023-11-13 Thread Salil Mehta via
Virtual CPU hotplug support is being added across various architectures[1][3].
This series adds various code bits common across all architectures:

1. vCPU creation and Parking code refactor [Patch 1]
2. Update ACPI GED framework to support vCPU Hotplug [Patch 2,3]
3. ACPI CPUs AML code change [Patch 4,5]
4. Helper functions to support unrealization of CPU objects [Patch 6,7]
5. Docs [Patch 8]


Repository:

[*] https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v2.common.v7


Revision History:

Patch-set  V6 -> V7
1. Addressed Alex Bennée's comments
   - Updated the docs
2. Addressed Igor Mammedov's comments
   - Merged patches [Patch V6 3/9] & [Patch V6 7/9] with [Patch V6 4/9]
   - Updated commit-log of [Patch V6 1/9] and [Patch V6 5/9] 
3. Added Shaoqin Huang's Reviewed-by tags for whole series.
Link: 
https://lore.kernel.org/qemu-devel/20231013105129.25648-1-salil.me...@huawei.com/

Patch-set  V5 -> V6
1. Addressed Gavin Shan's comments
   - Fixed the assert() ranges of address spaces
   - Rebased the patch-set to latest changes in the qemu.git
   - Added Reviewed-by tags for patches {8,9}
2. Addressed Jonathan Cameron's comments
   - Updated commit-log for [Patch V5 1/9] with mention of trace events
   - Added Reviewed-by tags for patches {1,5}
3. Added Tested-by tags from Xianglai Li
4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9] 
Link: 
https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/

Patch-set  V4 -> V5
1. Addressed Gavin Shan's comments
   - Fixed the trace events print string for kvm_{create,get,park,destroy}_vcpu
   - Added Reviewed-by tag for patch {1}
2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
4. Dropped the ARM specific [Patch V4 10/10]
Link: 
https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/

Patch-set  V3 -> V4
1. Addressed David Hilderbrand's comments
   - Fixed the wrong doc comment of kvm_park_vcpu API prototype
   - Added Reviewed-by tags for patches {2,4}
Link: 
https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/

Patch-set  V2 -> V3
1. Addressed Jonathan Cameron's comments
   - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
   - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
   - Updated [Patch V2 3/10] commit-log with details of ACPI_CPU_SCAN_METHOD 
macro
   - Updated [Patch V2 5/10] commit-log with details of conditional event 
handler method
   - Added Reviewed-by tags for patches {2,3,4,6,7}
2. Addressed Gavin Shan's comments
   - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
   - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
   - Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
   - Fixed the kvm_{create,park}_vcpu prototypes docs
   - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
3. Addressed one earlier missed comment by Alex Bennée in RFC V1
   - Added traces instead of DPRINTF in the newly added and some existing 
functions
Link: 
https://lore.kernel.org/qemu-devel/20230930001933.2660-1-salil.me...@huawei.com/

Patch-set V1 -> V2
1. Addressed Alex Bennée's comments
   - Refactored the kvm_create_vcpu logic to get rid of goto
   - Added the docs for kvm_{create,park}_vcpu prototypes
   - Splitted the gdbstub and AddressSpace destruction change into separate 
patches
   - Added Reviewed-by tags for patches {2,10}
Link: 
https://lore.kernel.org/qemu-devel/20230929124304.13672-1-salil.me...@huawei.com/

References:

[1] 
https://lore.kernel.org/qemu-devel/20230926100436.28284-1-salil.me...@huawei.com/
[2] https://lore.kernel.org/all/20230913163823.7880-1-james.mo...@arm.com/
[3] 
https://lore.kernel.org/qemu-devel/cover.1695697701.git.lixiang...@loongson.cn/



Salil Mehta (8):
  accel/kvm: Extract common KVM vCPU {creation,parking} code
  hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
  hw/acpi: Update ACPI GED framework to support vCPU Hotplug
  hw/acpi: Update GED _EVT method AML with CPU scan
  hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
  physmem: Add helper function to destroy CPU AddressSpace
  gdbstub: Add helper function to unregister GDB register space
  docs/specs/acpi_hw_reduced_hotplug: Add the CPU Hotplug Event Bit

 accel/kvm/kvm-all.c| 64 --
 accel/kvm/trace-events |  4 ++
 docs/specs/acpi_hw_reduced_hotplug.rst |  3 +-
 gdbstub/gdbstub.c  | 12 +
 hw/acpi/acpi-cpu-hotplug-stub.c|  6 +++
 hw/acpi/cpu.c  | 27 +++
 hw/acpi/generic_event_device.c | 21 +
 hw/i386/acpi-build.c   |  3 +-
 include/exec/cpu-common.h  |  8 
 include/exec/gdbstub.h |  5 ++
 include/hw/acpi/cpu.h  |  5 +-
 include/hw/acpi/cpu_hotplug.h  |  4 ++
 

RE: [PATCH V6 5/9] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

2023-11-13 Thread Salil Mehta via
Hi Igor,
Sorry, I missed this as well.

> From: Igor Mammedov 
> Sent: Friday, October 27, 2023 2:47 PM
> To: Salil Mehta ; m...@redhat.com
> 
> On Fri, 13 Oct 2023 11:51:25 +0100
> Salil Mehta  wrote:
> 
> > CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is 
> > based on
> > PCI and is IO port based and hence existing CPUs AML code assumes _CRS 
> > objects
>
> being placed in PCI0 context is no the reason why resource was described as 
> IO.
> being IO is probably historical thing (as legacy hp was implemented as IO)


I just meant that because it is IO port based therefore existing CPUs AML code
would evaluate to a system resource which describes IO Port address.



> _CRS could have been at _SB level as motherboard resource but, in that case
> we would need to carve out hole in PCI's _CRS  explicitly to exclude it.
> Hence it was placed in PCI0 context as a hack that helps to avoid us that.
> Perhaps it also applies to other targets.

Sure.

> > would evaluate to a system resource which describes IO Port address. But on 
> > ARM
> > arch CPUs control device(\\_SB.PRES) register interface is memory-mapped 
> > hence
> > _CRS object should evaluate to system resource which describes memory-mapped
> > base address. Update build CPUs AML function to accept both IO/MEMORY region
> > spaces and accordingly update the _CRS object.
> 
> Also x86 should be able to switch to and work with MMIO region
> (I think QEMU wise IO and MMIO are the same)
> and we can just use MMIO, likely without any compat machinery.
> 
> aka. existing/running/migrated x86 guests will use IO instructions to access 
> region
> (since CRS they have read, says it is IO), while new VMs will access region 
> as MMIO.


Ok got it. But I guess existing CPUs AML code for ctrl-dev did not have this
change. Or did I miss anything?

 
> I might be wrong though,
>   Michael?
> 
> > On x86, Legacy CPU Hotplug uses Generic ACPI GPE Block Bit 2 (GPE.2) event
> > handler to notify OSPM about any CPU hot(un)plug events. Latest CPU Hotplug 
> > is
> > based on ACPI Generic Event Device framework and uses ACPI GED device for 
> > the
> > same. Not all architectures support Legacy CPU Hotplug. Hence, make AML for
> > GPE.2 event handler conditional.
> 
> x86 has support for Legacy and Modern CPU hotplug (the later is enabled at 
> runtime).
> And both use GPE for event delivery, so above statement is not entirely 
> correct/confusing.

Ok yes. I will rephrase part of it.


Thanks
Salil.

> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Gavin Shan 
> > Tested-by: Vishnu Pajjuri 
> > Reviewed-by: Jonathan Cameron 
> > Tested-by: Xianglai Li 
> > ---
> >  hw/acpi/cpu.c | 23 ---
> >  hw/i386/acpi-build.c  |  3 ++-
> >  include/hw/acpi/cpu.h |  5 +++--
> >  3 files changed, 21 insertions(+), 10 deletions(-)
> >
> > diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
> > index 4b24a25003..596b6d9d81 100644
> > --- a/hw/acpi/cpu.c
> > +++ b/hw/acpi/cpu.c
> > @@ -339,9 +339,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
> >  #define CPU_FW_EJECT_EVENT "CEJF"
> >
> >  void build_cpus_aml(Aml *table, MachineState *machine,
> CPUHotplugFeatures opts,
> > -build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
> > +build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
> >  const char *res_root,
> > -const char *event_handler_method)
> > +const char *event_handler_method,
> > +AmlRegionSpace rs)
> >  {
> >  Aml *ifctx;
> >  Aml *field;
> > @@ -366,13 +367,19 @@ void build_cpus_aml(Aml *table, MachineState
> *machine, CPUHotplugFeatures opts,
> >  aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
> >
> >  crs = aml_resource_template();
> > -aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
> > +if (rs == AML_SYSTEM_IO) {
> > +aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr,
> 1,
> > ACPI_CPU_HOTPLUG_REG_LEN));
> > +} else {
> > +aml_append(crs, aml_memory32_fixed(base_addr,
> > +   ACPI_CPU_HOTPLUG_REG_LEN,
> AML_READ_WRITE));
> > +}
> > +
> >  aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
> >
> >  /* declare CPU hotplug MMIO region with related access fields */
> >  aml_append(cpu_ctrl_dev,
> > -aml_operation_region("PRST", AML_SYSTEM_IO,
> aml_int(io_base),
> > +aml_operation_region("PRST", rs, aml_int(base_addr),
> >   ACPI_CPU_HOTPLUG_REG_LEN));
> >
> >  field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
> > @@ -696,9 +703,11 @@ void build_cpus_aml(Aml *table, MachineState
> *machine, CPUHotplugFeatures opts,
> >  aml_append(sb_scope, cpus_dev);
> >  

RE: [PATCH V6 4/9] hw/acpi: Init GED framework with CPU hotplug events

2023-11-13 Thread Salil Mehta via
Hi Igor,
Sorry, I realized I missed to reply this review comment.

> From: Igor Mammedov 
> Sent: Friday, October 27, 2023 3:08 PM
> To: Salil Mehta 
> 
> On Fri, 13 Oct 2023 11:51:24 +0100
> Salil Mehta  wrote:
> 
> > ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI 
> > events
> > when OSPM/guest receives an interrupt listed in the _CRS object of GED. OSPM
> > then maps or demultiplexes the event by evaluating _EVT method.
> >
> > This change adds the support of CPU hotplug event initialization in the
> > existing GED framework.
> >
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Jonathan Cameron 
> > Reviewed-by: Gavin Shan 
> > Reviewed-by: David Hildenbrand 
> > Tested-by: Vishnu Pajjuri 
> > Tested-by: Xianglai Li 
> > ---
> >  hw/acpi/generic_event_device.c | 8 
> >  include/hw/acpi/generic_event_device.h | 5 +
> >  2 files changed, 13 insertions(+)
> >
> > diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
> > index a3d31631fe..d2fa1d0e4a 100644
> > --- a/hw/acpi/generic_event_device.c
> > +++ b/hw/acpi/generic_event_device.c
> > @@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = {
> >  ACPI_GED_MEM_HOTPLUG_EVT,
> >  ACPI_GED_PWR_DOWN_EVT,
> >  ACPI_GED_NVDIMM_HOTPLUG_EVT,
> > +ACPI_GED_CPU_HOTPLUG_EVT,
> >  };
> >
> >  /*
> > @@ -400,6 +401,13 @@ static void acpi_ged_initfn(Object *obj)
> >  memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
> >TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
> >  sysbus_init_mmio(sbd, _st->regs);
> > +
> > +s->cpuhp.device = OBJECT(s);
> ain't OBJECT(s) == OBJECT(dev)m


Thanks for pointing. And going deeper to looks this is *stray* and
surprisingly has been lurking since I first floated the RFC V1
in Jun 2020. Sorry I missed it in earlier context although David
did point to this.

Salil.


> > +memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp
> container",
> > +   ACPI_CPU_HOTPLUG_REG_LEN);
> > +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
> > +cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
> > +>cpuhp_state, 0);
> 
> we really should refactor GED to initfn/realizefn pattern.
> then at create_acpi_ged() one would enable cpu_hotplug event
> and later realizefs would call cpu_hotplug_hw_init() if event is enabled.


Maybe. Why not instance_init() ?


> >  }
> >
> >  static void acpi_ged_class_init(ObjectClass *class, void *data)
> > diff --git a/include/hw/acpi/generic_event_device.h
> b/include/hw/acpi/generic_event_device.h
> > index ba84ce0214..a803ea818e 100644
> > --- a/include/hw/acpi/generic_event_device.h
> > +++ b/include/hw/acpi/generic_event_device.h
> > @@ -60,6 +60,7 @@
> >  #define HW_ACPI_GENERIC_EVENT_DEVICE_H
> >
> >  #include "hw/sysbus.h"
> > +#include "hw/acpi/cpu_hotplug.h"
> >  #include "hw/acpi/memory_hotplug.h"
> >  #include "hw/acpi/ghes.h"
> >  #include "qom/object.h"
> > @@ -95,6 +96,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
> >  #define ACPI_GED_MEM_HOTPLUG_EVT   0x1
> >  #define ACPI_GED_PWR_DOWN_EVT  0x2
> >  #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
> > +#define ACPI_GED_CPU_HOTPLUG_EVT0x8
> >
> >  typedef struct GEDState {
> >  MemoryRegion evt;
> > @@ -106,6 +108,9 @@ struct AcpiGedState {
> >  SysBusDevice parent_obj;
> >  MemHotplugState memhp_state;
> >  MemoryRegion container_memhp;
> > +CPUHotplugState cpuhp_state;
> > +MemoryRegion container_cpuhp;
> > +AcpiCpuHotplug cpuhp;
> 
> how about merging CPUHotplugState and AcpiCpuHotplug
> and isolating AcpiCpuHotplug::sts to x86 legacy hotplug code only?
> 
> then you won't have to pull in 2 states (one of which includes
> GPE specific array that's not applicable to GED)

To be frank, I do not remember the context what I was trying to do
4 years back. But above looks stray and will remove it.


Thanks
Salil.




RE: [PATCH V6 7/9] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

2023-11-08 Thread Salil Mehta via
Hi Igor,

> From: Igor Mammedov 
> Sent: Friday, October 27, 2023 2:18 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; gs...@redhat.com;
> raf...@kernel.org; alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V6 7/9] hw/acpi: Update ACPI GED framework to support
> vCPU Hotplug
> 
> On Fri, 13 Oct 2023 11:51:27 +0100
> Salil Mehta  wrote:
> 
> > ACPI GED shall be used to convey to the guest kernel about any CPU 
> > hot-(un)plug
> > events. Therefore, existing ACPI GED framework inside QEMU needs to be 
> > enhanced
> > to support CPU hotplug state and events.
> >
> 
> This is a part of hw wiring which you started to introduce in 4/9
> Given patches are small, I'd merge this into 4/9 to avoid broken context.
> So essentially GED improvement would consist from hw and aml parts.
> with some extra refactoring (5/9) in a separate patch.


No issues. Will merge.

Thanks
Salil.

> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Jonathan Cameron 
> > Reviewed-by: Gavin Shan 
> > Tested-by: Vishnu Pajjuri 
> > Tested-by: Xianglai Li 
> > ---
> >  hw/acpi/generic_event_device.c | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
> > index 62d504d231..0d5f0140e5 100644
> > --- a/hw/acpi/generic_event_device.c
> > +++ b/hw/acpi/generic_event_device.c
> > @@ -12,6 +12,7 @@
> >  #include "qemu/osdep.h"
> >  #include "qapi/error.h"
> >  #include "hw/acpi/acpi.h"
> > +#include "hw/acpi/cpu.h"
> >  #include "hw/acpi/generic_event_device.h"
> >  #include "hw/irq.h"
> >  #include "hw/mem/pc-dimm.h"
> > @@ -239,6 +240,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler 
> > *hotplug_dev,
> >  } else {
> >  acpi_memory_plug_cb(hotplug_dev, >memhp_state, dev, errp);
> >  }
> > +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> > +acpi_cpu_plug_cb(hotplug_dev, >cpuhp_state, dev, errp);
> >  } else {
> >  error_setg(errp, "virt: device plug request for unsupported device"
> > " type: %s", object_get_typename(OBJECT(dev)));
> > @@ -253,6 +256,8 @@ static void acpi_ged_unplug_request_cb(HotplugHandler 
> > *hotplug_dev,
> >  if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> > !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM {
> >  acpi_memory_unplug_request_cb(hotplug_dev, >memhp_state, dev, 
> > errp);
> > +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> > +acpi_cpu_unplug_request_cb(hotplug_dev, >cpuhp_state, dev, 
> > errp);
> >  } else {
> >  error_setg(errp, "acpi: device unplug request for unsupported 
> > device"
> > " type: %s", object_get_typename(OBJECT(dev)));
> > @@ -266,6 +271,8 @@ static void acpi_ged_unplug_cb(HotplugHandler 
> > *hotplug_dev,
> >
> >  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >  acpi_memory_unplug_cb(>memhp_state, dev, errp);
> > +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> > +acpi_cpu_unplug_cb(>cpuhp_state, dev, errp);
> >  } else {
> >  error_setg(errp, "acpi: device unplug for unsupported device"
> > " type: %s", object_get_typename(OBJECT(dev)));
> > @@ -277,6 +284,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, 
> > ACPIOSTInfoList ***list)
> >  AcpiGedState *s = ACPI_GED(adev);
> >
> >  acpi_memory_ospm_status(>memhp_state, list);
> > +acpi_cpu_ospm_status(>cpuhp_state, list);
> >  }
> >
> >  static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
> > @@ -291,6 +299,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
> > AcpiEventStatusBits ev)
> >  sel = ACPI_GED_PWR_DOWN_EVT;
> >  } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
> >  sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
> > +} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
> > +sel = ACPI_GED_CPU_HOTPLUG_EVT;
> >  } else {
> >  /* Unknown event. Return without generating interrupt. */
> >  warn_report("GED: Unsupported event %d. No irq injected", ev);




RE: [PATCH V6 3/9] hw/acpi: Add ACPI CPU hotplug init stub

2023-11-06 Thread Salil Mehta via
Hi Igor,

> From: Igor Mammedov 
> Sent: Friday, October 27, 2023 2:06 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; gs...@redhat.com;
> raf...@kernel.org; alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V6 3/9] hw/acpi: Add ACPI CPU hotplug init stub
> 
> On Fri, 13 Oct 2023 11:51:23 +0100
> Salil Mehta  wrote:
> 
> > ACPI CPU hotplug related initialization should only happen if 
> > ACPI_CPU_HOTPLUG
> > support has been enabled for particular architecture. Add 
> > cpu_hotplug_hw_init()
> > stub to avoid compilation break.
> 
> merge this with 4/9 that actually requires this to be done.

Sure. No issues.


Thanks
Salil.


> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Jonathan Cameron 
> > Reviewed-by: Gavin Shan 
> > Reviewed-by: Shaoqin Huang 
> > Tested-by: Vishnu Pajjuri 
> > Tested-by: Xianglai Li 
> > ---
> >  hw/acpi/acpi-cpu-hotplug-stub.c | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-
> stub.c
> > index 3fc4b14c26..c6c61bb9cd 100644
> > --- a/hw/acpi/acpi-cpu-hotplug-stub.c
> > +++ b/hw/acpi/acpi-cpu-hotplug-stub.c
> > @@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion
> *parent, Object *owner,
> >  return;
> >  }
> >
> > +void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
> > + CPUHotplugState *state, hwaddr base_addr)
> > +{
> > +return;
> > +}
> > +
> >  void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList
> ***list)
> >  {
> >  return;
> 




RE: [PATCH V6 1/9] accel/kvm: Extract common KVM vCPU {creation,parking} code

2023-11-06 Thread Salil Mehta via
Hi Igor,
Thanks for the review comments. I was bit on and off so could not address
the comments. Please find my replies inline.

> From: Igor Mammedov 
> Sent: Friday, October 27, 2023 1:57 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; gs...@redhat.com;
> raf...@kernel.org; alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V6 1/9] accel/kvm: Extract common KVM vCPU
> {creation,parking} code
> 
> On Fri, 13 Oct 2023 11:51:21 +0100
> Salil Mehta  wrote:
> 
> > KVM vCPU creation is done once during the initialization of the VM when Qemu
> 
> > thread is spawned. This is common to all the architectures.
> 
> is it really true fox x86?

Thanks for pointing out. I just meant,

"KVM vCPU creation is done once either during VM initialization or during
vCPU realization during Hotplug"


> > Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
> > corresponding KVM vCPU object in the Host KVM is not destroyed and its
> ^
> since KVM doesn't support vCPU removal

Correct. Will add.


> > representative KVM vCPU object/context in Qemu is parked.
> >
> > Refactor common logic so that some APIs could be reused by vCPU Hotplug 
> > code.
> 'reused' part doesn't happen within this series. So a reason
> why patch exists is not clear/no one can deduce the reason
> without the actual user here.
> 
> Suggest to move it to a series that actually will use this patch.


I can do that but I think Loongson guys might need bit of this logic
as well. This patch also brings a good restructuring to the existing
code and fixes the traces etc.

I would humbly suggest to keep it unless you have strong views.

Thanks
Salil.

> > Update new/old APIs with trace events instead of DTRACE.
> >
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Gavin Shan 
> > Tested-by: Vishnu Pajjuri 
> > Reviewed-by: Jonathan Cameron 
> > Tested-by: Xianglai Li 
> > ---
> >  accel/kvm/kvm-all.c| 64 --
> >  accel/kvm/trace-events |  4 +++
> >  include/sysemu/kvm.h   | 16 +++
> >  3 files changed, 69 insertions(+), 15 deletions(-)
> >
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> > index 72e1d1141c..bfa7816aaa 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -137,6 +137,7 @@ static QemuMutex kml_slots_lock;
> >  #define kvm_slots_unlock()  qemu_mutex_unlock(_slots_lock)
> >
> >  static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
> > +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
> >
> >  static inline void kvm_resample_fd_remove(int gsi)
> >  {
> > @@ -320,14 +321,53 @@ err:
> >  return ret;
> >  }
> >
> > +void kvm_park_vcpu(CPUState *cpu)
> > +{
> > +struct KVMParkedVcpu *vcpu;
> > +
> > +trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
> > +
> > +vcpu = g_malloc0(sizeof(*vcpu));
> > +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
> > +vcpu->kvm_fd = cpu->kvm_fd;
> > +QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
> > +}
> > +
> > +int kvm_create_vcpu(CPUState *cpu)
> > +{
> > +unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
> > +KVMState *s = kvm_state;
> > +int kvm_fd;
> > +
> > +trace_kvm_create_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
> > +
> > +/* check if the KVM vCPU already exist but is parked */
> > +kvm_fd = kvm_get_vcpu(s, vcpu_id);
> > +if (kvm_fd < 0) {
> > +/* vCPU not parked: create a new KVM vCPU */
> > +kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
> > +if (kvm_fd < 0) {
> > +error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu",
> vcpu_id);
> > +return kvm_fd;
> > +}
> > +}
> > +
> > +cpu->kvm_fd = kvm_fd;
> > +cpu->kvm_state = s;
> > +cpu->vcpu_dirty = true;
> > +cpu->dirty_pages = 0;
> > +cpu->throttle_us_per_full = 0;
> > +
> > +return 0;
> > +}
> > +
> >  static int do_kvm_destroy_vcpu(CPUState *cpu)
> >  {
> >  KVMState *s = kvm_state;
> >  long mmap_size;
> > -struct KVMParkedVcpu *vcpu = NULL;
> >  int ret = 0;
> >
> > -DPRINTF("kvm_destroy_vcpu\n");
> > +trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
> >
> >  ret = 

RE: [PATCH V6 0/9] Add architecture agnostic code to support vCPU Hotplug

2023-10-27 Thread Salil Mehta via
Hi Igor,

> From: Igor Mammedov 
> Sent: Thursday, October 26, 2023 1:41 PM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; gs...@redhat.com;
> raf...@kernel.org; alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V6 0/9] Add architecture agnostic code to support vCPU
> Hotplug
> 
> On Fri, 13 Oct 2023 11:51:20 +0100
> Salil Mehta  wrote:
> 
> > Virtual CPU hotplug support is being added across various
> architectures[1][3].
> > This series adds various code bits common across all architectures:
> >
> > 1. vCPU creation and Parking code refactor [Patch 1]
> > 2. Update ACPI GED framework to support vCPU Hotplug [Patch 4,6,7]
> > 3. ACPI CPUs AML code change [Patch 5]
> > 4. Helper functions to support unrealization of CPU objects [Patch 8,9]
> > 5. Misc [Patch 2,3]
> 
> Thanks Salil!
> 
> Overall series looks good to me (modulo some points, I'd like to be addressed)
> I'll do some testing and follow with per patch review tomorrow.

Many thanks! that would be helpful.

Meanwhile, I am preparing the V7 version of this to address the x86/microvm
qtest break reported by Miguel.

https://lore.kernel.org/qemu-devel/51b6c120-3707-4730-ae14-0f5cd32dc...@oracle.com/


Solution suggested here:
https://lore.kernel.org/qemu-devel/15e70616-6abb-63a4-17d0-820f4a254...@opnsrc.net/T/#m108f102b2fe92b7dd7218f2f942f7b233a9d6af3


cheers
Salil.


> > Repository:
> >
> > [*] https://github.com/salil-mehta/qemu.git 
> > virt-cpuhp-armv8/rfc-v2.common.v6
> >
> >
> > Revision History:
> >
> > Patch-set  V5 -> V6
> > 1. Addressed Gavin Shan's comments
> >- Fixed the assert() ranges of address spaces
> >- Rebased the patch-set to latest changes in the qemu.git
> >- Added Reviewed-by tags for patches {8,9}
> > 2. Addressed Jonathan Cameron's comments
> >- Updated commit-log for [Patch V5 1/9] with mention of trace events
> >- Added Reviewed-by tags for patches {1,5}
> > 3. Added Tested-by tags from Xianglai Li
> > 4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9]
> > Link: 
> > https://lore.kernel.org/qemu-devel/20231011194355.15628-1-salil.me...@huawei.com/
> >
> > Patch-set  V4 -> V5
> > 1. Addressed Gavin Shan's comments
> >- Fixed the trace events print string for 
> > kvm_{create,get,park,destroy}_vcpu
> >- Added Reviewed-by tag for patch {1}
> > 2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
> > 3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
> > 4. Dropped the ARM specific [Patch V4 10/10]
> > Link: 
> > https://lore.kernel.org/qemu-devel/20231009203601.17584-1-salil.me...@huawei.com/
> >
> > Patch-set  V3 -> V4
> > 1. Addressed David Hilderbrand's comments
> >- Fixed the wrong doc comment of kvm_park_vcpu API prototype
> >- Added Reviewed-by tags for patches {2,4}
> > Link: 
> > https://lore.kernel.org/qemu-devel/20231009112812.10612-1-salil.me...@huawei.com/
> >
> > Patch-set  V2 -> V3
> > 1. Addressed Jonathan Cameron's comments
> >- Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to 'integer'
> >- Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
> >- Updated [Patch V2 3/10] commit-log with details of 
> > ACPI_CPU_SCAN_METHOD macro
> >- Updated [Patch V2 5/10] commit-log with details of conditional event 
> > handler method
> >- Added Reviewed-by tags for patches {2,3,4,6,7}
> > 2. Addressed Gavin Shan's comments
> >- Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
> >- Fixed return value in kvm_get_vcpu from -1 to -ENOENT
> >- Reset the value of 'gdb_num_g_regs' in gdb_unregister_coprocessor_all
> >- Fixed the kvm_{create,park}_vcpu prototypes docs
> >- Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
> > 3. Addressed one earlier missed comment by Alex Bennée in RFC V1
> >- Added traces instead of DPRINTF in the newly added and some existing 
> > functions
> > Link: https://lore.kernel.org/qemu-devel/20230930001933.2660-1- 
> > salil.me...@huawei.com/
> >
> > Patch-set V1 -> V2
> > 1. Addressed Alex Bennée's comments
> >- Refactored the kvm_create_vcpu logic to get rid of goto
> >- Added the docs for kvm_{create,park}_vcpu prototypes
> >- Splitted the gdbstub and AddressSpace destruction change into separate 
> > patches
> >- Added Reviewed-by tags for patches {2,10}
> > Link: 
> > 

RE: [Question] x86/microvm: why has_hotpluggable_cpus = false but hot(ub)plug APIs exist?

2023-10-27 Thread Salil Mehta via

> From: Igor Mammedov 
> Sent: Thursday, October 26, 2023 1:09 PM
> To: Salil Mehta 
> 
> On Wed, 25 Oct 2023 09:54:07 +
> Salil Mehta  wrote:
> 
> > > From: David Hildenbrand 
> > > Sent: Wednesday, October 25, 2023 10:32 AM
> > > To: Salil Mehta ; Igor Mammedov
> > > ; Salil Mehta 
> > >
> > > On 25.10.23 11:16, Salil Mehta wrote:
> > > > Hi Igor,
> > > >
> > > >> From: Igor Mammedov 
> > > >> Sent: Tuesday, October 24, 2023 9:06 AM
> > > >> To: Salil Mehta 
> > > >>
> > > >> On Wed, 18 Oct 2023 17:48:36 +0100
> > > >> Salil Mehta  wrote:
> > > >>
> > > >>> Hi Alex,
> > > >>>
> > > >>> On 18/10/2023 16:41, Alex Bennée wrote:
> > > 
> > >  Salil Mehta  writes:
> > > 
> > > > Hello,
> > > >
> > > > Came across below code excerpt in x86/microvm code and wanted to 
> > > > know
> > > > why 'has_hotpluggable_cpus' flag has been set to 'false' while 
> > > > various
> > > > hot(un)plug APIs have been defined?
> > > >
> > > > static void microvm_class_init(ObjectClass *oc, void *data)
> > > > {
> > > >   X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
> > > >   MachineClass *mc = MACHINE_CLASS(oc);
> > > >   HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
> > > >
> > > >   mc->init = microvm_machine_state_init;
> > > >
> > > >   mc->family = "microvm_i386";
> > > >   [...]
> > > >   mc->max_cpus = 288;
> > > >   mc->has_hotpluggable_cpus = false;  > This one
> > > >   [...]
> > > 
> > >    From the original commit that added it:
> > > 
> > >  It's a minimalist machine type without PCI nor ACPI support, 
> > >  designed
> > >  for short-lived guests. microvm also establishes a baseline for
> > >  benchmarking and optimizing both QEMU and guest operating 
> > >  systems,
> > >  since it is optimized for both boot time and footprint.
> > > >>>
> > > >>>
> > > >>> Agreed. It looks like ACPI is supported but neither CPU/Memory Hotplug
> > > >>> is supported for this minimalist machine type.
> > > >>>
> > > >>>
> > > >>> static void microvm_devices_init(MicrovmMachineState *mms)
> > > >>> {
> > > >>>   const char *default_firmware;
> > > >>>   X86MachineState *x86ms = X86_MACHINE(mms);
> > > >>>
> > > >>>  [...]
> > > >>>
> > > >>>   /* Optional and legacy devices */
> > > >>>   if (x86_machine_is_acpi_enabled(x86ms)) {
> > > >>>   DeviceState *dev = qdev_new(TYPE_ACPI_GED_X86);
> > > >>>   qdev_prop_set_uint32(dev, "ged-event", 
> > > >>> ACPI_GED_PWR_DOWN_EVT);
> > > >>>   sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_MMIO_BASE);
> > > >>>/* sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, 
> > > >>> GED_MMIO_BASE_MEMHP);
> > > */
> > > >>>
> > > >>>   [...]
> > > >>>
> > > >>>   sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
> > > >>>   x86ms->acpi_dev = HOTPLUG_HANDLER(dev);
> > > >>>   }
> > > >>>  [...]
> > > >>> }
> > > >>>
> > > 
> > >  Generally hotplug requires a dance between the VMM and the firmware 
> > >  to
> > >  properly shutdown and restart hotplug devices. The principle
> > >  communication mechanism for this is ACPI.
> > > >>
> > > >> firmware part in cpu/mem hoptlug usually provided by QEMU by the way of
> > > >> ACPI tables (which may contain AML code that handles dance with QEMU
> > > >> while exposing standard interface to guest OS to handle hotplug)
> > > >>
> > > >>>
> > > >>> Agreed.
> > > >>>
> > > >   /* hotplug (for cpu coldplug) */
> > > >   mc->get_hotplug_handler = microvm_get_hotplug_handler;
> > > >   hc->pre_plug = microvm_device_pre_plug_cb;
> > > >   hc->plug = microvm_device_plug_cb;
> > > >   hc->unplug_request = microvm_device_unplug_request_cb;
> > > >   hc->unplug = microvm_device_unplug_cb;
> > > >>>
> > > >>> sorry, I also missed the definitions of the last 2 functions which 
> > > >>> says
> > > >>> that unplug is not supported so perhaps these functions are only
> > > >>> required to support cold plugging which corroborates with the comment 
> > > >>> as
> > > >>> well.
> > > >>
> > > >> this function are usually used for both cold and hotplug of bus-less 
> > > >> devices.
> > > >> They provide an opt-in way for board to wire up such devices (incl. 
> > > >> CPU).
> > > >
> > > >
> > > > Sure. I understand but microvm does not support hotplug so presence of
> > > > unplug{_request} versions brought a doubt in my mind but I realized 
> > > > later
> > > > that their definitions were empty. Cold-plug does not require unplug
> > > > versions.
> > > >
> > > > Was there any plan to support hot-plug with microvm in future?
> > >
> > > At least virtio-mem for memory hotplug should be fairly straight- forward
> > > to wire-up I guess. The relation to ACPI are minimal: we currently only
> > > use ACPI SRAT to expose the maximum GPA range that 

RE: [Question] x86/microvm: why has_hotpluggable_cpus = false but hot(ub)plug APIs exist?

2023-10-25 Thread Salil Mehta via
> From: David Hildenbrand 
> Sent: Wednesday, October 25, 2023 10:32 AM
> To: Salil Mehta ; Igor Mammedov
> ; Salil Mehta 
> 
> On 25.10.23 11:16, Salil Mehta wrote:
> > Hi Igor,
> >
> >> From: Igor Mammedov 
> >> Sent: Tuesday, October 24, 2023 9:06 AM
> >> To: Salil Mehta 
> >>
> >> On Wed, 18 Oct 2023 17:48:36 +0100
> >> Salil Mehta  wrote:
> >>
> >>> Hi Alex,
> >>>
> >>> On 18/10/2023 16:41, Alex Bennée wrote:
> 
>  Salil Mehta  writes:
> 
> > Hello,
> >
> > Came across below code excerpt in x86/microvm code and wanted to know
> > why 'has_hotpluggable_cpus' flag has been set to 'false' while various
> > hot(un)plug APIs have been defined?
> >
> > static void microvm_class_init(ObjectClass *oc, void *data)
> > {
> >   X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
> >   MachineClass *mc = MACHINE_CLASS(oc);
> >   HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
> >
> >   mc->init = microvm_machine_state_init;
> >
> >   mc->family = "microvm_i386";
> >   [...]
> >   mc->max_cpus = 288;
> >   mc->has_hotpluggable_cpus = false;  > This one
> >   [...]
> 
>    From the original commit that added it:
> 
>  It's a minimalist machine type without PCI nor ACPI support, designed
>  for short-lived guests. microvm also establishes a baseline for
>  benchmarking and optimizing both QEMU and guest operating systems,
>  since it is optimized for both boot time and footprint.
> >>>
> >>>
> >>> Agreed. It looks like ACPI is supported but neither CPU/Memory Hotplug
> >>> is supported for this minimalist machine type.
> >>>
> >>>
> >>> static void microvm_devices_init(MicrovmMachineState *mms)
> >>> {
> >>>   const char *default_firmware;
> >>>   X86MachineState *x86ms = X86_MACHINE(mms);
> >>>
> >>>  [...]
> >>>
> >>>   /* Optional and legacy devices */
> >>>   if (x86_machine_is_acpi_enabled(x86ms)) {
> >>>   DeviceState *dev = qdev_new(TYPE_ACPI_GED_X86);
> >>>   qdev_prop_set_uint32(dev, "ged-event", ACPI_GED_PWR_DOWN_EVT);
> >>>   sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_MMIO_BASE);
> >>>/* sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_MMIO_BASE_MEMHP);
> */
> >>>
> >>>   [...]
> >>>
> >>>   sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
> >>>   x86ms->acpi_dev = HOTPLUG_HANDLER(dev);
> >>>   }
> >>>  [...]
> >>> }
> >>>
> 
>  Generally hotplug requires a dance between the VMM and the firmware to
>  properly shutdown and restart hotplug devices. The principle
>  communication mechanism for this is ACPI.
> >>
> >> firmware part in cpu/mem hoptlug usually provided by QEMU by the way of
> >> ACPI tables (which may contain AML code that handles dance with QEMU
> >> while exposing standard interface to guest OS to handle hotplug)
> >>
> >>>
> >>> Agreed.
> >>>
> >   /* hotplug (for cpu coldplug) */
> >   mc->get_hotplug_handler = microvm_get_hotplug_handler;
> >   hc->pre_plug = microvm_device_pre_plug_cb;
> >   hc->plug = microvm_device_plug_cb;
> >   hc->unplug_request = microvm_device_unplug_request_cb;
> >   hc->unplug = microvm_device_unplug_cb;
> >>>
> >>> sorry, I also missed the definitions of the last 2 functions which says
> >>> that unplug is not supported so perhaps these functions are only
> >>> required to support cold plugging which corroborates with the comment as
> >>> well.
> >>
> >> this function are usually used for both cold and hotplug of bus-less 
> >> devices.
> >> They provide an opt-in way for board to wire up such devices (incl. CPU).
> >
> >
> > Sure. I understand but microvm does not support hotplug so presence of
> > unplug{_request} versions brought a doubt in my mind but I realized later
> > that their definitions were empty. Cold-plug does not require unplug
> > versions.
> >
> > Was there any plan to support hot-plug with microvm in future?
> 
> At least virtio-mem for memory hotplug should be fairly straight-forward
> to wire-up I guess. The relation to ACPI are minimal: we currently only
> use ACPI SRAT to expose the maximum GPA range that e.g., Linux requires
> early during boot to properly prepare for memory hotplug (size the
> virtual memory space for the kernel accordingly). One could use
> alternative (paravirtualized) interfaces for that.

Ok. Light weight VM more in lines of Firecracker to improve boot-up times?

Also, presence of unplug versions gives a wrong impression about code?

> The question is whether any form of hotplug is "in the spirit" of microvm.

Understand that. BTW, was it ever made to be used with kata-containers?

Thanks
Salil.


RE: [Question] x86/microvm: why has_hotpluggable_cpus = false but hot(ub)plug APIs exist?

2023-10-25 Thread Salil Mehta via
Hi Igor,

> From: Igor Mammedov 
> Sent: Tuesday, October 24, 2023 9:06 AM
> To: Salil Mehta 
> 
> On Wed, 18 Oct 2023 17:48:36 +0100
> Salil Mehta  wrote:
> 
> > Hi Alex,
> >
> > On 18/10/2023 16:41, Alex Bennée wrote:
> > >
> > > Salil Mehta  writes:
> > >
> > >> Hello,
> > >>
> > >> Came across below code excerpt in x86/microvm code and wanted to know
> > >> why 'has_hotpluggable_cpus' flag has been set to 'false' while various
> > >> hot(un)plug APIs have been defined?
> > >>
> > >> static void microvm_class_init(ObjectClass *oc, void *data)
> > >> {
> > >>  X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
> > >>  MachineClass *mc = MACHINE_CLASS(oc);
> > >>  HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
> > >>
> > >>  mc->init = microvm_machine_state_init;
> > >>
> > >>  mc->family = "microvm_i386";
> > >>  [...]
> > >>  mc->max_cpus = 288;
> > >>  mc->has_hotpluggable_cpus = false;  > This one
> > >>  [...]
> > >
> > >  From the original commit that added it:
> > >
> > >It's a minimalist machine type without PCI nor ACPI support, designed
> > >for short-lived guests. microvm also establishes a baseline for
> > >benchmarking and optimizing both QEMU and guest operating systems,
> > >since it is optimized for both boot time and footprint.
> >
> >
> > Agreed. It looks like ACPI is supported but neither CPU/Memory Hotplug
> > is supported for this minimalist machine type.
> >
> >
> > static void microvm_devices_init(MicrovmMachineState *mms)
> > {
> >  const char *default_firmware;
> >  X86MachineState *x86ms = X86_MACHINE(mms);
> >
> > [...]
> >
> >  /* Optional and legacy devices */
> >  if (x86_machine_is_acpi_enabled(x86ms)) {
> >  DeviceState *dev = qdev_new(TYPE_ACPI_GED_X86);
> >  qdev_prop_set_uint32(dev, "ged-event", ACPI_GED_PWR_DOWN_EVT);
> >  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_MMIO_BASE);
> >   /* sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_MMIO_BASE_MEMHP); */
> >
> >  [...]
> >
> >  sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
> >  x86ms->acpi_dev = HOTPLUG_HANDLER(dev);
> >  }
> > [...]
> > }
> >
> > >
> > > Generally hotplug requires a dance between the VMM and the firmware to
> > > properly shutdown and restart hotplug devices. The principle
> > > communication mechanism for this is ACPI.
> 
> firmware part in cpu/mem hoptlug usually provided by QEMU by the way of
> ACPI tables (which may contain AML code that handles dance with QEMU
> while exposing standard interface to guest OS to handle hotplug)
> 
> >
> > Agreed.
> >
> > >>  /* hotplug (for cpu coldplug) */
> > >>  mc->get_hotplug_handler = microvm_get_hotplug_handler;
> > >>  hc->pre_plug = microvm_device_pre_plug_cb;
> > >>  hc->plug = microvm_device_plug_cb;
> > >>  hc->unplug_request = microvm_device_unplug_request_cb;
> > >>  hc->unplug = microvm_device_unplug_cb;
> >
> > sorry, I also missed the definitions of the last 2 functions which says
> > that unplug is not supported so perhaps these functions are only
> > required to support cold plugging which corroborates with the comment as
> > well.
> 
> this function are usually used for both cold and hotplug of bus-less devices.
> They provide an opt-in way for board to wire up such devices (incl. CPU).


Sure. I understand but microvm does not support hotplug so presence of
unplug{_request} versions brought a doubt in my mind but I realized later
that their definitions were empty. Cold-plug does not require unplug
versions. 

Was there any plan to support hot-plug with microvm in future?


Thanks
Salil.







RE: [PATCH V6 4/9] hw/acpi: Init GED framework with CPU hotplug events

2023-10-19 Thread Salil Mehta via
Hi Alex,

> From: Alex Bennée 
> Sent: Thursday, October 19, 2023 11:16 AM
> To: Salil Mehta 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org; m...@kernel.org; jean-
> phili...@linaro.org; Jonathan Cameron ;
> lpieral...@kernel.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; imamm...@redhat.com; andrew.jo...@linux.dev;
> da...@redhat.com; phi...@linaro.org; eric.au...@redhat.com;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> w...@kernel.org; gs...@redhat.com; raf...@kernel.org;
> li...@armlinux.org.uk; dar...@os.amperecomputing.com;
> il...@os.amperecomputing.com; vis...@os.amperecomputing.com;
> karl.heub...@oracle.com; miguel.l...@oracle.com; salil.me...@opnsrc.net;
> zhukeqian ; wangxiongfeng (C)
> ; wangyanan (Y) ;
> jiakern...@gmail.com; maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm
> 
> Subject: Re: [PATCH V6 4/9] hw/acpi: Init GED framework with CPU hotplug
> events
> 
> 
> Salil Mehta  writes:
> 
> > ACPI GED(as described in the ACPI 6.2 spec) can be used to generate ACPI 
> > events
> > when OSPM/guest receives an interrupt listed in the _CRS object of GED. OSPM
> > then maps or demultiplexes the event by evaluating _EVT method.
> >
> > This change adds the support of CPU hotplug event initialization in the
> > existing GED framework.
> 
> Should we also update the docs here:
> 
>   https://qemu.readthedocs.io/en/master/specs/acpi_hw_reduced_hotplug.html
> 
> (see docs/specs/acpi_hw_reduced_hotplug.rst)


Good point. Will do.


> to add the new bits? Or maybe an update to documentation as the last
> commit?

Will add one more patch at the last for this documentation change.

Thanks for identifying this.

Cheers
Salil.


> 
> >
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > Reviewed-by: Jonathan Cameron 
> > Reviewed-by: Gavin Shan 
> > Reviewed-by: David Hildenbrand 
> > Tested-by: Vishnu Pajjuri 
> > Tested-by: Xianglai Li 
> > ---
> >  hw/acpi/generic_event_device.c | 8 
> >  include/hw/acpi/generic_event_device.h | 5 +
> >  2 files changed, 13 insertions(+)
> >
> > diff --git a/hw/acpi/generic_event_device.c
> b/hw/acpi/generic_event_device.c
> > index a3d31631fe..d2fa1d0e4a 100644
> > --- a/hw/acpi/generic_event_device.c
> > +++ b/hw/acpi/generic_event_device.c
> > @@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = {
> >  ACPI_GED_MEM_HOTPLUG_EVT,
> >  ACPI_GED_PWR_DOWN_EVT,
> >  ACPI_GED_NVDIMM_HOTPLUG_EVT,
> > +ACPI_GED_CPU_HOTPLUG_EVT,
> >  };
> >
> >  /*
> > @@ -400,6 +401,13 @@ static void acpi_ged_initfn(Object *obj)
> >  memory_region_init_io(_st->regs, obj, _regs_ops, ged_st,
> >TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
> >  sysbus_init_mmio(sbd, _st->regs);
> > +
> > +s->cpuhp.device = OBJECT(s);
> > +memory_region_init(>container_cpuhp, OBJECT(dev), "cpuhp
> container",
> > +   ACPI_CPU_HOTPLUG_REG_LEN);
> > +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container_cpuhp);
> > +cpu_hotplug_hw_init(>container_cpuhp, OBJECT(dev),
> > +>cpuhp_state, 0);
> >  }
> >
> >  static void acpi_ged_class_init(ObjectClass *class, void *data)
> > diff --git a/include/hw/acpi/generic_event_device.h
> b/include/hw/acpi/generic_event_device.h
> > index ba84ce0214..a803ea818e 100644
> > --- a/include/hw/acpi/generic_event_device.h
> > +++ b/include/hw/acpi/generic_event_device.h
> > @@ -60,6 +60,7 @@
> >  #define HW_ACPI_GENERIC_EVENT_DEVICE_H
> >
> >  #include "hw/sysbus.h"
> > +#include "hw/acpi/cpu_hotplug.h"
> >  #include "hw/acpi/memory_hotplug.h"
> >  #include "hw/acpi/ghes.h"
> >  #include "qom/object.h"
> > @@ -95,6 +96,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
> >  #define ACPI_GED_MEM_HOTPLUG_EVT   0x1
> >  #define ACPI_GED_PWR_DOWN_EVT  0x2
> >  #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
> > +#define ACPI_GED_CPU_HOTPLUG_EVT0x8
> >
> >  typedef struct GEDState {
> >  MemoryRegion evt;
> > @@ -106,6 +108,9 @@ struct AcpiGedState {
> >  SysBusDevice parent_obj;
> >  MemHotplugState memhp_state;
> >  MemoryRegion container_memhp;
> > +CPUHotplugState cpuhp_state;
> > +MemoryRegion container_cpuhp;
> > +AcpiCpuHotplug cpuhp;
> >  GEDState ged_state;
> >  uint32_t ged_event_bitmap;
> >  qemu_irq irq;
> 
> 
> --
> Alex Bennée
> Virtualisation Tech Lead @ Linaro



RE: [PATCH V6 0/9] Add architecture agnostic code to support vCPU Hotplug

2023-10-19 Thread Salil Mehta via
Hi Shaoqin,

> From: Shaoqin Huang 
> Sent: Thursday, October 19, 2023 10:05 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; qemu-
> a...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; oliver.up...@linux.dev;
> pbonz...@redhat.com; m...@redhat.com; w...@kernel.org; gs...@redhat.com;
> raf...@kernel.org; alex.ben...@linaro.org; li...@armlinux.org.uk;
> dar...@os.amperecomputing.com; il...@os.amperecomputing.com;
> vis...@os.amperecomputing.com; karl.heub...@oracle.com;
> miguel.l...@oracle.com; salil.me...@opnsrc.net; zhukeqian
> ; wangxiongfeng (C) ;
> wangyanan (Y) ; jiakern...@gmail.com;
> maob...@loongson.cn; lixiang...@loongson.cn; Linuxarm 
> Subject: Re: [PATCH V6 0/9] Add architecture agnostic code to support vCPU
> Hotplug
> 
> 
> 
> On 10/13/23 18:51, Salil Mehta via wrote:
> > Virtual CPU hotplug support is being added across various
> architectures[1][3].
> > This series adds various code bits common across all architectures:
> >
> > 1. vCPU creation and Parking code refactor [Patch 1]
> > 2. Update ACPI GED framework to support vCPU Hotplug [Patch 4,6,7]
> > 3. ACPI CPUs AML code change [Patch 5]
> > 4. Helper functions to support unrealization of CPU objects [Patch 8,9]
> > 5. Misc [Patch 2,3]
> >
> >
> > Repository:
> >
> > [*] https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-
> v2.common.v6
> >
> >
> > Revision History:
> >
> > Patch-set  V5 -> V6
> > 1. Addressed Gavin Shan's comments
> > - Fixed the assert() ranges of address spaces
> > - Rebased the patch-set to latest changes in the qemu.git
> > - Added Reviewed-by tags for patches {8,9}
> > 2. Addressed Jonathan Cameron's comments
> > - Updated commit-log for [Patch V5 1/9] with mention of trace events
> > - Added Reviewed-by tags for patches {1,5}
> > 3. Added Tested-by tags from Xianglai Li
> > 4. Fixed checkpatch.pl error "Qemu -> QEMU" in [Patch V5 1/9]
> > Link: https://lore.kernel.org/qemu-devel/20231011194355.15628-1-
> salil.me...@huawei.com/
> >
> > Patch-set  V4 -> V5
> > 1. Addressed Gavin Shan's comments
> > - Fixed the trace events print string for
> kvm_{create,get,park,destroy}_vcpu
> > - Added Reviewed-by tag for patch {1}
> > 2. Added Shaoqin Huang's Reviewed-by tags for Patches {2,3}
> > 3. Added Tested-by Tag from Vishnu Pajjuri to the patch-set
> > 4. Dropped the ARM specific [Patch V4 10/10]
> > Link: https://lore.kernel.org/qemu-devel/20231009203601.17584-1-
> salil.me...@huawei.com/
> >
> > Patch-set  V3 -> V4
> > 1. Addressed David Hilderbrand's comments
> > - Fixed the wrong doc comment of kvm_park_vcpu API prototype
> > - Added Reviewed-by tags for patches {2,4}
> > Link: https://lore.kernel.org/qemu-devel/20231009112812.10612-1-
> salil.me...@huawei.com/
> >
> > Patch-set  V2 -> V3
> > 1. Addressed Jonathan Cameron's comments
> > - Fixed 'vcpu-id' type wrongly changed from 'unsigned long' to
> 'integer'
> > - Removed unnecessary use of variable 'vcpu_id' in kvm_park_vcpu
> > - Updated [Patch V2 3/10] commit-log with details of
> ACPI_CPU_SCAN_METHOD macro
> > - Updated [Patch V2 5/10] commit-log with details of conditional
> event handler method
> > - Added Reviewed-by tags for patches {2,3,4,6,7}
> > 2. Addressed Gavin Shan's comments
> > - Remove unnecessary use of variable 'vcpu_id' in kvm_par_vcpu
> > - Fixed return value in kvm_get_vcpu from -1 to -ENOENT
> > - Reset the value of 'gdb_num_g_regs' in
> gdb_unregister_coprocessor_all
> > - Fixed the kvm_{create,park}_vcpu prototypes docs
> > - Added Reviewed-by tags for patches {2,3,4,5,6,7,9,10}
> > 3. Addressed one earlier missed comment by Alex Bennée in RFC V1
> > - Added traces instead of DPRINTF in the newly added and some
> existing functions
> > Link: https://lore.kernel.org/qemu-devel/20230930001933.2660-1-
> salil.me...@huawei.com/
> >
> > Patch-set V1 -> V2
> > 1. Addressed Alex Bennée's comments
> > - Refactored the kvm_create_vcpu logic to get rid of goto
> > - Added the docs for kvm_{create,park}_vcpu prototypes
> > - Splitted the gdbstub and AddressSpace destruction change into
> separate patches
> > - Added Reviewed-by tags for patches {2,10}
> > Link: https://lore.kernel.org/qemu

RE: [PATCH RFC V2 35/37] hw/arm: Support hotplug capability check using _OSC method

2023-10-16 Thread Salil Mehta via
Hi Gavin,

> From: Gavin Shan 
> Sent: Friday, September 29, 2023 5:23 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; 
> qemu-...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; w...@kernel.org; a...@kernel.org;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> raf...@kernel.org; borntrae...@linux.ibm.com; alex.ben...@linaro.org;
> li...@armlinux.org.uk; dar...@os.amperecomputing.com;
> il...@os.amperecomputing.com; vis...@os.amperecomputing.com;
> karl.heub...@oracle.com; miguel.l...@oracle.com; salil.me...@opnsrc.net;
> zhukeqian ; wangxiongfeng (C)
> ; wangyanan (Y) ;
> jiakern...@gmail.com; maob...@loongson.cn; lixiang...@loongson.cn
> Subject: Re: [PATCH RFC V2 35/37] hw/arm: Support hotplug capability check
> using _OSC method
> 
> Hi Salil,
> 
> On 9/26/23 20:36, Salil Mehta wrote:
> > Physical CPU hotplug results in (un)setting of ACPI _STA.Present bit. 
> > AARCH64
> > platforms do not support physical CPU hotplug. Virtual CPU Hotplug support 
> > being
> > implemented toggles ACPI _STA.Enabled Bit to achieve Hotplug functionality. 
> > This
> > is not same as physical CPU hotplug support.
> >
> > In future, if ARM architecture supports physical CPU hotplug then the 
> > current
> > design of virtual CPU hotplug can be used unchanged. Hence, there is a need 
> > for
> > firmware/VMM/Qemu to support evaluation of platform wide capabilitiy 
> > related to
> > the *type* of CPU hotplug support present on the platform. OSPM might need 
> > this
> > during boot time to correctly initialize the CPUs and other related 
> > components
> > in the kernel.
> >
> > NOTE: This implementation will be improved to add the support of *query* in 
> > the
> > subsequent versions. This is very minimal support to assist kernel.
> >
> > ASL for the implemented _OSC method:
> >
> > Method (_OSC, 4, NotSerialized)  // _OSC: Operating System Capabilities
> > {
> >  CreateDWordField (Arg3, Zero, CDW1)
> >  If ((Arg0 == ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48") /* 
> > Platform-wide Capabilities */))
> >  {
> >  CreateDWordField (Arg3, 0x04, CDW2)
> >  Local0 = CDW2 /* \_SB_._OSC.CDW2 */
> >  If ((Arg1 != One))
> >  {
> >  CDW1 |= 0x08
> >  }
> >
> >  Local0 &= 0x0080
> >  If ((CDW2 != Local0))
> >  {
> >  CDW1 |= 0x10
> >  }
> >
> >  CDW2 = Local0
> >  }
> >  Else
> >  {
> >  CDW1 |= 0x04
> >  }
> >
> >  Return (Arg3)
> > }
> >
> > Signed-off-by: Salil Mehta 
> > ---
> >   hw/arm/virt-acpi-build.c | 52 
> >   1 file changed, 52 insertions(+)
> >
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index cbccd2ca2d..377450dd16 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -861,6 +861,55 @@ static void build_fadt_rev6(GArray *table_data, 
> > BIOSLinker *linker,
> >   build_fadt(table_data, linker, , vms->oem_id, vms-
> >oem_table_id);
> >   }
> >
> > +static void build_virt_osc_method(Aml *scope, VirtMachineState *vms)
> > +{
> > +Aml *if_uuid, *else_uuid, *if_rev, *if_caps_masked, *method;
> > +Aml *a_cdw1 = aml_name("CDW1");
> > +Aml *a_cdw2 = aml_local(0);
> > +
> > +method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> > +aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), 
> > "CDW1"));
> > +
> > +/* match UUID */
> > +if_uuid = aml_if(aml_equal(
> > +aml_arg(0), aml_touuid("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")));
> > +
> > +aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(4), 
> > "CDW2"));
> > +aml_append(if_uuid, aml_store(aml_name("CDW2"), a_cdw2));
> > +
> > +/* check unknown revision in arg(1) */
> > +if_rev = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1;
> > +/* set revision error bits,  DWORD1 Bit[3] */
> > +aml_append(if_rev, aml_or(a_cdw1, aml_int(0x08), a_cdw1));
> > +aml_append(if_uuid, if_rev);
> > +
> > +/*
> > + * check support for vCPU hotplug type(=enabled) platform-wide 
> > capability
> > + * in DWORD2 as sepcified in the below ACPI Specification ECR,
> > + *  # https://bugzilla.tianocore.org/show_bug.cgi?id=4481
> > + */
> > +if (vms->acpi_dev) {
> > +aml_append(if_uuid, aml_and(a_cdw2, aml_int(0x80), a_cdw2));
> > +/* check if OSPM specified hotplug capability bits were masked */
> > +if_caps_masked = aml_if(aml_lnot(aml_equal(aml_name("CDW2"), 
> > a_cdw2)));
> > +aml_append(if_caps_masked, aml_or(a_cdw1, aml_int(0x10), a_cdw1));
> > +aml_append(if_uuid, if_caps_masked);
> > +}
> > +aml_append(if_uuid, aml_store(a_cdw2, aml_name("CDW2")));

RE: [PATCH RFC V2 34/37] target/arm/kvm,tcg: Register/Handle SMCCC hypercall exits to VMM/Qemu

2023-10-16 Thread Salil Mehta via
Hi Gavin,

> From: Gavin Shan 
> Sent: Friday, September 29, 2023 5:15 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; 
> qemu-...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; w...@kernel.org; a...@kernel.org;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> raf...@kernel.org; borntrae...@linux.ibm.com; alex.ben...@linaro.org;
> li...@armlinux.org.uk; dar...@os.amperecomputing.com;
> il...@os.amperecomputing.com; vis...@os.amperecomputing.com;
> karl.heub...@oracle.com; miguel.l...@oracle.com; salil.me...@opnsrc.net;
> zhukeqian ; wangxiongfeng (C)
> ; wangyanan (Y) ;
> jiakern...@gmail.com; maob...@loongson.cn; lixiang...@loongson.cn
> Subject: Re: [PATCH RFC V2 34/37] target/arm/kvm,tcg: Register/Handle SMCCC
> hypercall exits to VMM/Qemu
> 
> Hi Salil,
> 
> On 9/26/23 20:36, Salil Mehta wrote:
> > From: Author Salil Mehta 
> >
> > Add registration and Handling of HVC/SMC hypercall exits to VMM
> >
> > Co-developed-by: Salil Mehta 
> > Signed-off-by: Salil Mehta 
> > Co-developed-by: Jean-Philippe Brucker 
> > Signed-off-by: Jean-Philippe Brucker 
> > Signed-off-by: Salil Mehta 

[...]

> > +static CPUArchId *arm_get_archid_by_id(uint64_t id)
> > +{
> > +int n;
> > +CPUArchId *arch_id;
> > +MachineState *ms = MACHINE(qdev_get_machine());
> > +
> > +/*
> > + * At this point disabled CPUs don't have a CPUState, but their 
> > CPUArchId
> > + * exists.
> > + *
> > + * TODO: Is arch_id == mp_affinity? This needs work.
> > + */
> > +for (n = 0; n < ms->possible_cpus->len; n++) {
> > +arch_id = >possible_cpus->cpus[n];
> > +
> > +if (arch_id->arch_id == id) {
> > +return arch_id;
> > +}
> > +}
> > +return NULL;
> > +}
> > +
> 
> The @arch_id should be same thing to @mp_affinity except for the boot CPU.
> For the boot CPU, its value is fetched from MPIDR, which is determined by
> cs->cpu_index, passed to host via ioctl(CREATE_VCPU). Besides, another
> similiar function qemu_get_cpu_archid() exists in cpus-common.c. I think
> they can be combined. Again, all these information inherited from
> ms->possible_cpus may be better to be managed in board level, like the
> vCPU states.

Yes, good catch. This has been existing for long so my eyes got biased.


Thanks
Salil.


[...]

> > @@ -168,12 +189,24 @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry,
> uint64_t context_id,
> >   }
> >
> >   /* Retrieve the cpu we are powering up */
> > -target_cpu_state = arm_get_cpu_by_id(cpuid);
> > -if (!target_cpu_state) {
> > +arch_id = arm_get_archid_by_id(cpuid);
> > +if (!arch_id) {
> >   /* The cpu was not found */
> >   return QEMU_ARM_POWERCTL_INVALID_PARAM;
> >   }
> >
> > +target_cpu_state = CPU(arch_id->cpu);
> > +if (!qemu_enabled_cpu(target_cpu_state)) {
> > +/*
> > + * The cpu is not plugged in or disabled. We should return 
> > appropriate
> > + * value as introduced in DEN0022E PSCI 1.2 issue E
> ^^^
> issue E, which is 
> QEMU_PSCI_RET_DENIED.

   PSCI_RET_DENIED


[...]

> > --- a/target/arm/helper.c
> > +++ b/target/arm/helper.c
> > @@ -11187,7 +11187,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
> > env->exception.syndrome);
> >   }
> >
> > -if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
> > +if (arm_is_psci_call(cpu, cs->exception_index)) {
> >   arm_handle_psci_call(cpu);
> >   qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
> >   return;
> 
> We may still limit the capability to handle PSCI calls to TCG and KVM,
> meaning HVF and QTest won't have this capability.


We do not support them now. I need to conditionally register SMCC calls
With KVM. Will check this. Good point though.

Thanks
Salil.


[...]

> > diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> > index 8e7c68af6a..6f3fd5aecd 100644
> > --- a/target/arm/kvm.c
> > +++ b/target/arm/kvm.c
> > @@ -250,6 +250,7 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms,
> bool *fixed_ipa)
> >   int kvm_arch_init(MachineState *ms, KVMState *s)
> >   {
> >   int ret = 0;
> > +
>
> Unnecessary change.

Yes.

Thanks.


[...]

> > @@ -280,6 +281,22 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
> >   }
> >   }
> >
> > +/*
> > + * To be able to handle PSCI CPU ON calls in QEMU, we need to install 
> > SMCCC
>  ^^
>  ON/OFF

Yes.

> > + * filter in the Host KVM. This is required to support features like
> > + * virtual CPU Hotplug on ARM 

RE: [PATCH RFC V2 29/37] arm/virt: Update the guest(via GED) about CPU hot-(un)plug events

2023-10-16 Thread Salil Mehta via
Hi Gavin,

> From: Gavin Shan 
> Sent: Friday, September 29, 2023 1:31 AM
> To: Salil Mehta ; qemu-devel@nongnu.org; 
> qemu-...@nongnu.org
> Cc: m...@kernel.org; jean-phili...@linaro.org; Jonathan Cameron
> ; lpieral...@kernel.org;
> peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; andrew.jo...@linux.dev; da...@redhat.com;
> phi...@linaro.org; eric.au...@redhat.com; w...@kernel.org; a...@kernel.org;
> oliver.up...@linux.dev; pbonz...@redhat.com; m...@redhat.com;
> raf...@kernel.org; borntrae...@linux.ibm.com; alex.ben...@linaro.org;
> li...@armlinux.org.uk; dar...@os.amperecomputing.com;
> il...@os.amperecomputing.com; vis...@os.amperecomputing.com;
> karl.heub...@oracle.com; miguel.l...@oracle.com; salil.me...@opnsrc.net;
> zhukeqian ; wangxiongfeng (C)
> ; wangyanan (Y) ;
> jiakern...@gmail.com; maob...@loongson.cn; lixiang...@loongson.cn
> Subject: Re: [PATCH RFC V2 29/37] arm/virt: Update the guest(via GED) about
> CPU hot-(un)plug events
> 
> Hi Salil,
> 
> On 9/26/23 20:04, Salil Mehta wrote:
> > During any vCPU hot-(un)plug, running guest VM needs to be intimated about 
> > the
> > new vCPU being added or request the deletion of the vCPU which is already 
> > part
> > of the guest VM. This is done using the ACPI GED event which eventually gets
> > demultiplexed to a CPU hotplug event and further to specific hot-(un)plug 
> > event
> > of a particular vCPU.
> >
> > This change adds the ACPI calls to the existing hot-(un)plug hooks to 
> > trigger
> > ACPI GED events from QEMU to guest VM.
> >
> > Co-developed-by: Salil Mehta 
> > Signed-off-by: Salil Mehta 
> > Co-developed-by: Keqian Zhu 
> > Signed-off-by: Keqian Zhu 
> > Signed-off-by: Salil Mehta 
> > ---

[...]

> > @@ -3169,12 +3170,20 @@ static void virt_cpu_plug(HotplugHandler 
> > *hotplug_dev, DeviceState *dev,
> >* plugged, guest is also notified.
> >*/
> >   if (vms->acpi_dev) {
> > -/* TODO: update acpi hotplug state. Send cpu hotplug event to 
> > guest */
> > +HotplugHandlerClass *hhc;
> > +/* update acpi hotplug state and send cpu hotplug event to guest */
> > +hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
> > +hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, _err);
> > +if (local_err) {
> > +goto fail;
> > +}
> >   /* TODO: register cpu for reset & update F/W info for the next 
> > boot */
> >   }
> >
> >   cs->disabled = false;
> >   return;
> > +fail:
> > +error_propagate(errp, local_err);
> >   }
> >
> 
> 'fail' tag isn't needed since it's used for once. we can bail early:
> 
>  if (local_err) {
> error_propagate(errp, local_err);
> return;
>  }


Agreed. Indeed we can remove goto.


[...]

> > @@ -3202,9 +3213,16 @@ static void virt_cpu_unplug_request(HotplugHandler 
> > *hotplug_dev,
> >   return;
> >   }
> >
> > -/* TODO: request cpu hotplug from guest */
> > +/* request cpu hotplug from guest */
> > +hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
> > +hhc->unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev, _err);
> > +if (local_err) {
> > +goto fail;
> > +}
> >
> >   return;
> > +fail:
> > +error_propagate(errp, local_err);
> >   }
> >
> 
> Same as above, 'fail' tag isn't needed. Besides, 'return' isn't needed.


Agreed. We can remove goto



[...]

> > @@ -3222,7 +3242,12 @@ static void virt_cpu_unplug(HotplugHandler
> *hotplug_dev, DeviceState *dev,
> >
> >   cpu_slot = virt_find_cpu_slot(ms, cs->cpu_index);
> >
> > -/* TODO: update the acpi cpu hotplug state for cpu hot-unplug */
> > +/* update the acpi cpu hotplug state for cpu hot-unplug */
> > +hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
> > +hhc->unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, _err);
> > +if (local_err) {
> > +goto fail;
> > +}
> >
> >   unwire_gic_cpu_irqs(vms, cs);
> >   virt_update_gic(vms, cs);
> > @@ -3236,6 +3261,8 @@ static void virt_cpu_unplug(HotplugHandler
> *hotplug_dev, DeviceState *dev,
> >   cs->disabled = true;
> >
> >   return;
> > +fail:
> > +error_propagate(errp, local_err);
> >   }
> >
> 
> Same as above.


Agreed. Will fix.


Thanks
Salil.


  1   2   3   4   >