@@ -655,15 +655,13 @@ static void fw_cfg_add_memory(MachineState *ms)
static void virt_init(MachineState *machine)
{
- LoongArchCPU *lacpu;
const char *cpu_model = machine->cpu_type;
MemoryRegion *address_space_mem = get_system_memory();
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
int i;
hwaddr base, size, ram_size = machine->ram_size;
- const CPUArchIdList *possible_cpus;
MachineClass *mc = MACHINE_GET_CLASS(machine);
- CPUState *cpu;
+ Object *cpuobj;
if (!cpu_model) {
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -679,14 +677,15 @@ static void virt_init(MachineState *machine)
memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
/* Init CPUs */
- possible_cpus = mc->possible_cpu_arch_ids(machine);
- for (i = 0; i < possible_cpus->len; i++) {
- cpu = cpu_create(machine->cpu_type);
- cpu->cpu_index = i;
- machine->possible_cpus->cpus[i].cpu = cpu;
- lacpu = LOONGARCH_CPU(cpu);
- lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
- lacpu->env.address_space_iocsr = &lvms->as_iocsr;
+ mc->possible_cpu_arch_ids(machine);
+ for (i = 0; i < machine->smp.cpus; i++) {
+ cpuobj = object_new(machine->cpu_type);
+ if (cpuobj == NULL) {
+ error_report("Fail to create object with type %s ",
+ machine->cpu_type);
+ exit(EXIT_FAILURE);
+ }
+ qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
}
fw_cfg_add_memory(machine);
@@ -837,9 +836,52 @@ static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
return NULL;
}
+/* Find cpu slot for cold-plut CPU object where cpu is NULL */
+static CPUArchId *virt_find_empty_cpu_slot(MachineState *ms)
+{
+ int n;
+ for (n = 0; n < ms->possible_cpus->len; n++) {
+ if (ms->possible_cpus->cpus[n].cpu == NULL) {
+ return &ms->possible_cpus->cpus[n];
+ }
+ }
+
+ return NULL;
+}
+
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
+ MachineState *ms = MACHINE(OBJECT(hotplug_dev));
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+ CPUState *cs = CPU(dev);
+ CPUArchId *cpu_slot;
+ Error *err = NULL;
+ LoongArchCPUTopo topo;
+
+ if (lvms->acpi_ged) {
+ error_setg(&err, "CPU hotplug not supported");
+ goto out;
+ } else {
+ /* For cold-add cpu, find empty cpu slot */
+ cpu_slot = virt_find_empty_cpu_slot(ms);
+ topo.socket_id = cpu_slot->props.socket_id;
+ topo.core_id = cpu_slot->props.core_id;
+ topo.thread_id = cpu_slot->props.thread_id;
+ object_property_set_int(OBJECT(dev), "socket-id", topo.socket_id, NULL);
+ object_property_set_int(OBJECT(dev), "core-id", topo.core_id, NULL);
+ object_property_set_int(OBJECT(dev), "thread-id", topo.thread_id, NULL);
+ }
+
+ cpu->env.address_space_iocsr = &lvms->as_iocsr;
+ cpu->phy_id = cpu_slot->arch_id;
+ cs->cpu_index = cpu_slot - ms->possible_cpus->cpus;
+ numa_cpu_pre_plug(cpu_slot, dev, &err);
+out:
+ if (err) {
+ error_propagate(errp, err);
+ }
}
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
@@ -900,6 +942,30 @@ static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ CPUArchId *cpu_slot;
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
+ Error *err = NULL;
+
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
+ cpu_slot->cpu = CPU(dev);
+ if (lvms->ipi) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+
+ if (lvms->extioi) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+
+ return;
}
static bool memhp_type_supported(DeviceState *dev)
@@ -962,6 +962,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
#ifdef CONFIG_TCG
cc->tcg_ops = &loongarch_tcg_ops;
#endif
+ dc->user_creatable = true;
}
static const gchar *loongarch32_gdb_arch_name(CPUState *cs)
Implement cpu plug interface, and cold-plug cpu uses plug interface when cpu object is created. Co-developed-by: Xianglai Li <lixianglai@loongson.cn> Signed-off-by: Bibo Mao <maobibo@loongson.cn> --- hw/loongarch/virt.c | 88 ++++++++++++++++++++++++++++++++++++------ target/loongarch/cpu.c | 1 + 2 files changed, 78 insertions(+), 11 deletions(-)