diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/i386/pc.c | 7 | ||||
| -rw-r--r-- | hw/i386/x86.c | 42 | ||||
| -rw-r--r-- | hw/s390x/s390-skeys.c | 2 | ||||
| -rw-r--r-- | hw/s390x/s390-stattrib-kvm.c | 4 | ||||
| -rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 22 | ||||
| -rw-r--r-- | hw/s390x/sclp.c | 17 |
6 files changed, 69 insertions, 25 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0bf0aaca52..5143c51653 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1526,6 +1526,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, env->nr_dies = x86ms->smp_dies; env->nr_nodes = topo_info.nodes_per_pkg; + env->pkg_offset = x86ms->apicid_pkg_offset(&topo_info); /* * If APIC ID is not set, @@ -1580,14 +1581,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, topo_ids.die_id = cpu->die_id; topo_ids.core_id = cpu->core_id; topo_ids.smt_id = cpu->thread_id; - cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); + cpu->apic_id = x86ms->apicid_from_topo_ids(&topo_info, &topo_ids); } cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx); if (!cpu_slot) { MachineState *ms = MACHINE(pcms); - x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); + x86ms->topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); error_setg(errp, "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" " APIC ID %" PRIu32 ", valid index range 0:%d", @@ -1608,7 +1609,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn() * once -smp refactoring is complete and there will be CPU private * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */ - x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); + x86ms->topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) { error_setg(errp, "property socket-id: %u doesn't match set apic-id:" " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 6ca3cf936f..b82770024c 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -69,6 +69,22 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info, } /* + * Set up with the new EPYC topology handlers + * + * AMD uses different apic id encoding for EPYC based cpus. Override + * the default topo handlers with EPYC encoding handlers. + */ +static void x86_set_epyc_topo_handlers(MachineState *machine) +{ + X86MachineState *x86ms = X86_MACHINE(machine); + + x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc; + x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc; + x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc; + x86ms->apicid_pkg_offset = apicid_pkg_offset_epyc; +} + +/* * Calculates initial APIC ID for a specific CPU index * * Currently we need to be able to calculate the APIC ID from the CPU index @@ -86,7 +102,7 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, init_topo_info(&topo_info, x86ms); - correct_id = x86_apicid_from_cpu_idx(&topo_info, cpu_index); + correct_id = x86ms->apicid_from_cpu_idx(&topo_info, cpu_index); if (x86mc->compat_apic_id_mode) { if (cpu_index != correct_id && !warned && !qtest_enabled()) { error_report("APIC IDs set in compatibility mode, " @@ -121,6 +137,11 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) MachineState *ms = MACHINE(x86ms); MachineClass *mc = MACHINE_GET_CLASS(x86ms); + /* Check for apicid encoding */ + if (cpu_x86_use_epyc_apic_id_encoding(ms->cpu_type)) { + x86_set_epyc_topo_handlers(ms); + } + x86_cpu_set_default_version(default_cpu_version); /* @@ -134,6 +155,12 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms, ms->smp.max_cpus - 1) + 1; possible_cpus = mc->possible_cpu_arch_ids(ms); + + for (i = 0; i < ms->possible_cpus->len; i++) { + ms->possible_cpus->cpus[i].arch_id = + x86_cpu_apic_id_from_index(x86ms, i); + } + for (i = 0; i < ms->smp.cpus; i++) { x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); } @@ -158,8 +185,7 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) init_topo_info(&topo_info, x86ms); assert(idx < ms->possible_cpus->len); - x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, - &topo_info, &topo_ids); + x86_topo_ids_from_idx(&topo_info, idx, &topo_ids); return topo_ids.pkg_id % ms->numa_state->num_nodes; } @@ -190,10 +216,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) ms->possible_cpus->cpus[i].type = ms->cpu_type; ms->possible_cpus->cpus[i].vcpus_count = 1; - ms->possible_cpus->cpus[i].arch_id = - x86_cpu_apic_id_from_index(x86ms, i); - x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, - &topo_info, &topo_ids); + x86_topo_ids_from_idx(&topo_info, i, &topo_ids); ms->possible_cpus->cpus[i].props.has_socket_id = true; ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; if (x86ms->smp_dies > 1) { @@ -937,6 +960,11 @@ static void x86_machine_initfn(Object *obj) x86ms->acpi = ON_OFF_AUTO_AUTO; x86ms->max_ram_below_4g = 0; /* use default */ x86ms->smp_dies = 1; + + x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx; + x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid; + x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids; + x86ms->apicid_pkg_offset = apicid_pkg_offset; } static void x86_machine_class_init(ObjectClass *oc, void *data) diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index 5da6e5292f..a9a4ae7b39 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -176,7 +176,7 @@ static void qemu_s390_skeys_init(Object *obj) QEMUS390SKeysState *skeys = QEMU_S390_SKEYS(obj); MachineState *machine = MACHINE(qdev_get_machine()); - skeys->key_count = machine->maxram_size / TARGET_PAGE_SIZE; + skeys->key_count = machine->ram_size / TARGET_PAGE_SIZE; skeys->keydata = g_malloc0(skeys->key_count); } diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c index c7e1f35524..f89d8d9d16 100644 --- a/hw/s390x/s390-stattrib-kvm.c +++ b/hw/s390x/s390-stattrib-kvm.c @@ -85,7 +85,7 @@ static int kvm_s390_stattrib_set_stattr(S390StAttribState *sa, { KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa); MachineState *machine = MACHINE(qdev_get_machine()); - unsigned long max = machine->maxram_size / TARGET_PAGE_SIZE; + unsigned long max = machine->ram_size / TARGET_PAGE_SIZE; if (start_gfn + count > max) { error_report("Out of memory bounds when setting storage attributes"); @@ -104,7 +104,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa) { KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa); MachineState *machine = MACHINE(qdev_get_machine()); - unsigned long max = machine->maxram_size / TARGET_PAGE_SIZE; + unsigned long max = machine->ram_size / TARGET_PAGE_SIZE; /* We do not need to reach the maximum buffer size allowed */ unsigned long cx, len = KVM_S390_SKEYS_MAX / 2; int r; diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 895498cca6..0fa00a9fff 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -26,6 +26,7 @@ #include "qemu/ctype.h" #include "qemu/error-report.h" #include "qemu/option.h" +#include "qemu/qemu-print.h" #include "s390-pci-bus.h" #include "sysemu/reset.h" #include "hw/s390x/storage-keys.h" @@ -439,6 +440,26 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp) s390_cpu_restart(S390_CPU(cs)); } +static ram_addr_t s390_fixup_ram_size(ram_addr_t sz) +{ + /* same logic as in sclp.c */ + int increment_size = 20; + ram_addr_t newsz; + + while ((sz >> increment_size) > MAX_STORAGE_INCREMENTS) { + increment_size++; + } + newsz = sz >> increment_size << increment_size; + + if (sz != newsz) { + qemu_printf("Ram size %" PRIu64 "MB was fixed up to %" PRIu64 + "MB to match machine restrictions. Consider updating " + "the guest definition.\n", (uint64_t) (sz / MiB), + (uint64_t) (newsz / MiB)); + } + return newsz; +} + static void ccw_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -668,6 +689,7 @@ static void ccw_machine_4_2_instance_options(MachineState *machine) static void ccw_machine_4_2_class_options(MachineClass *mc) { ccw_machine_5_0_class_options(mc); + mc->fixup_ram_size = s390_fixup_ram_size; compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len); } DEFINE_CCW_MACHINE(4_2, "4.2", false); diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index af0bfbc2ec..f0c35aa57a 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -327,27 +327,20 @@ out: static void sclp_memory_init(SCLPDevice *sclp) { MachineState *machine = MACHINE(qdev_get_machine()); + MachineClass *machine_class = MACHINE_GET_CLASS(qdev_get_machine()); ram_addr_t initial_mem = machine->ram_size; int increment_size = 20; /* The storage increment size is a multiple of 1M and is a power of 2. - * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer. + * For some machine types, the number of storage increments must be + * MAX_STORAGE_INCREMENTS or fewer. * The variable 'increment_size' is an exponent of 2 that can be * used to calculate the size (in bytes) of an increment. */ - while ((initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) { + while (machine_class->fixup_ram_size != NULL && + (initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) { increment_size++; } sclp->increment_size = increment_size; - - /* The core memory area needs to be aligned with the increment size. - * In effect, this can cause the user-specified memory size to be rounded - * down to align with the nearest increment boundary. */ - initial_mem = initial_mem >> increment_size << increment_size; - - machine->ram_size = initial_mem; - machine->maxram_size = initial_mem; - /* let's propagate the changed ram size into the global variable. */ - ram_size = initial_mem; } static void sclp_init(Object *obj) |