diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-06-28 21:04:22 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-06-28 21:04:22 +0100 |
commit | 6512fa497c2fa9751b9d774ab32d87a9764d1958 (patch) | |
tree | 710075b3ee9deb554b4dbcb70f37855b3d140151 /hw | |
parent | 9e654e10197f5a014eccd71de5ea633c1b0f4303 (diff) | |
parent | 0aebebb561c9c23b9c6d3d58040f83547f059b5c (diff) | |
download | qemu-6512fa497c2fa9751b9d774ab32d87a9764d1958.zip qemu-6512fa497c2fa9751b9d774ab32d87a9764d1958.tar.gz qemu-6512fa497c2fa9751b9d774ab32d87a9764d1958.tar.bz2 |
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* Some Meson test conversions
* KVM dirty page ring buffer fix
* KVM TSC scaling support
* Fixes for SG_IO with /dev/sdX devices
* (Non)support for host devices on iOS
* -smp cleanups
# gpg: Signature made Fri 25 Jun 2021 15:16:18 BST
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini-gitlab/tags/for-upstream: (28 commits)
machine: reject -smp dies!=1 for non-PC machines
machine: pass QAPI struct to mc->smp_parse
machine: add error propagation to mc->smp_parse
machine: move common smp_parse code to caller
machine: move dies from X86MachineState to CpuTopology
file-posix: handle EINTR during ioctl
block: detect DKIOCGETBLOCKCOUNT/SIZE before use
block: try BSD disk size ioctls one after another
block: check for sys/disk.h
block: feature detection for host block support
file-posix: try BLKSECTGET on block devices too, do not round to power of 2
block: add max_hw_transfer to BlockLimits
block-backend: align max_transfer to request alignment
osdep: provide ROUND_DOWN macro
scsi-generic: pass max_segments via max_iov field in BlockLimits
file-posix: fix max_iov for /dev/sg devices
KVM: Fix dirty ring mmap incorrect size due to renaming accident
configure, meson: convert libusbredir detection to meson
configure, meson: convert libcacard detection to meson
configure, meson: convert libusb detection to meson
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/core/machine.c | 132 | ||||
-rw-r--r-- | hw/i386/pc.c | 108 | ||||
-rw-r--r-- | hw/i386/x86.c | 15 | ||||
-rw-r--r-- | hw/scsi/scsi-generic.c | 6 | ||||
-rw-r--r-- | hw/usb/meson.build | 6 |
5 files changed, 139 insertions, 128 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c index 55b9bc7..ffc076a 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -739,69 +739,63 @@ void machine_set_cpu_numa_node(MachineState *machine, } } -static void smp_parse(MachineState *ms, QemuOpts *opts) +static void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp) { - if (opts) { - unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); - unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); - unsigned cores = qemu_opt_get_number(opts, "cores", 0); - unsigned threads = qemu_opt_get_number(opts, "threads", 0); - - /* compute missing values, prefer sockets over cores over threads */ - if (cpus == 0 || sockets == 0) { - cores = cores > 0 ? cores : 1; - threads = threads > 0 ? threads : 1; - if (cpus == 0) { - sockets = sockets > 0 ? sockets : 1; - cpus = cores * threads * sockets; - } else { - ms->smp.max_cpus = - qemu_opt_get_number(opts, "maxcpus", cpus); - sockets = ms->smp.max_cpus / (cores * threads); - } - } else if (cores == 0) { - threads = threads > 0 ? threads : 1; - cores = cpus / (sockets * threads); - cores = cores > 0 ? cores : 1; - } else if (threads == 0) { - threads = cpus / (cores * sockets); - threads = threads > 0 ? threads : 1; - } else if (sockets * cores * threads < cpus) { - error_report("cpu topology: " - "sockets (%u) * cores (%u) * threads (%u) < " - "smp_cpus (%u)", - sockets, cores, threads, cpus); - exit(1); - } + unsigned cpus = config->has_cpus ? config->cpus : 0; + unsigned sockets = config->has_sockets ? config->sockets : 0; + unsigned cores = config->has_cores ? config->cores : 0; + unsigned threads = config->has_threads ? config->threads : 0; - ms->smp.max_cpus = - qemu_opt_get_number(opts, "maxcpus", cpus); + if (config->has_dies && config->dies != 0 && config->dies != 1) { + error_setg(errp, "dies not supported by this machine's CPU topology"); + } - if (ms->smp.max_cpus < cpus) { - error_report("maxcpus must be equal to or greater than smp"); - exit(1); + /* compute missing values, prefer sockets over cores over threads */ + if (cpus == 0 || sockets == 0) { + cores = cores > 0 ? cores : 1; + threads = threads > 0 ? threads : 1; + if (cpus == 0) { + sockets = sockets > 0 ? sockets : 1; + cpus = cores * threads * sockets; + } else { + ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus; + sockets = ms->smp.max_cpus / (cores * threads); } + } else if (cores == 0) { + threads = threads > 0 ? threads : 1; + cores = cpus / (sockets * threads); + cores = cores > 0 ? cores : 1; + } else if (threads == 0) { + threads = cpus / (cores * sockets); + threads = threads > 0 ? threads : 1; + } else if (sockets * cores * threads < cpus) { + error_setg(errp, "cpu topology: " + "sockets (%u) * cores (%u) * threads (%u) < " + "smp_cpus (%u)", + sockets, cores, threads, cpus); + return; + } - if (sockets * cores * threads != ms->smp.max_cpus) { - error_report("Invalid CPU topology: " - "sockets (%u) * cores (%u) * threads (%u) " - "!= maxcpus (%u)", - sockets, cores, threads, - ms->smp.max_cpus); - exit(1); - } + ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus; - ms->smp.cpus = cpus; - ms->smp.cores = cores; - ms->smp.threads = threads; - ms->smp.sockets = sockets; + if (ms->smp.max_cpus < cpus) { + error_setg(errp, "maxcpus must be equal to or greater than smp"); + return; } - if (ms->smp.cpus > 1) { - Error *blocker = NULL; - error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); - replay_add_blocker(blocker); + if (sockets * cores * threads != ms->smp.max_cpus) { + error_setg(errp, "Invalid CPU topology: " + "sockets (%u) * cores (%u) * threads (%u) " + "!= maxcpus (%u)", + sockets, cores, threads, + ms->smp.max_cpus); + return; } + + ms->smp.cpus = cpus; + ms->smp.cores = cores; + ms->smp.threads = threads; + ms->smp.sockets = sockets; } static void machine_class_init(ObjectClass *oc, void *data) @@ -970,6 +964,7 @@ static void machine_initfn(Object *obj) ms->smp.cpus = mc->default_cpus; ms->smp.max_cpus = mc->default_cpus; ms->smp.cores = 1; + ms->smp.dies = 1; ms->smp.threads = 1; ms->smp.sockets = 1; } @@ -1133,8 +1128,29 @@ MemoryRegion *machine_consume_memdev(MachineState *machine, bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp) { MachineClass *mc = MACHINE_GET_CLASS(ms); + ERRP_GUARD(); - mc->smp_parse(ms, opts); + if (opts) { + SMPConfiguration config = { + .has_cpus = !!qemu_opt_get(opts, "cpus"), + .cpus = qemu_opt_get_number(opts, "cpus", 0), + .has_sockets = !!qemu_opt_get(opts, "sockets"), + .sockets = qemu_opt_get_number(opts, "sockets", 0), + .has_dies = !!qemu_opt_get(opts, "dies"), + .dies = qemu_opt_get_number(opts, "dies", 0), + .has_cores = !!qemu_opt_get(opts, "cores"), + .cores = qemu_opt_get_number(opts, "cores", 0), + .has_threads = !!qemu_opt_get(opts, "threads"), + .threads = qemu_opt_get_number(opts, "threads", 0), + .has_maxcpus = !!qemu_opt_get(opts, "maxcpus"), + .maxcpus = qemu_opt_get_number(opts, "maxcpus", 0), + }; + + mc->smp_parse(ms, &config, errp); + if (*errp) { + return false; + } + } /* sanity-check smp_cpus and max_cpus against mc */ if (ms->smp.cpus < mc->min_cpus) { @@ -1150,6 +1166,12 @@ bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp) mc->name, mc->max_cpus); return false; } + + if (ms->smp.cpus > 1) { + Error *blocker = NULL; + error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); + replay_add_blocker(blocker); + } return true; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c6d8d0d..8e1220d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -710,73 +710,61 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) * This function is very similar to smp_parse() * in hw/core/machine.c but includes CPU die support. */ -void pc_smp_parse(MachineState *ms, QemuOpts *opts) +static void pc_smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp) { - X86MachineState *x86ms = X86_MACHINE(ms); - - if (opts) { - unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); - unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); - unsigned dies = qemu_opt_get_number(opts, "dies", 1); - unsigned cores = qemu_opt_get_number(opts, "cores", 0); - unsigned threads = qemu_opt_get_number(opts, "threads", 0); - - /* compute missing values, prefer sockets over cores over threads */ - if (cpus == 0 || sockets == 0) { - cores = cores > 0 ? cores : 1; - threads = threads > 0 ? threads : 1; - if (cpus == 0) { - sockets = sockets > 0 ? sockets : 1; - cpus = cores * threads * dies * sockets; - } else { - ms->smp.max_cpus = - qemu_opt_get_number(opts, "maxcpus", cpus); - sockets = ms->smp.max_cpus / (cores * threads * dies); - } - } else if (cores == 0) { - threads = threads > 0 ? threads : 1; - cores = cpus / (sockets * dies * threads); - cores = cores > 0 ? cores : 1; - } else if (threads == 0) { - threads = cpus / (cores * dies * sockets); - threads = threads > 0 ? threads : 1; - } else if (sockets * dies * cores * threads < cpus) { - error_report("cpu topology: " - "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < " - "smp_cpus (%u)", - sockets, dies, cores, threads, cpus); - exit(1); - } - - ms->smp.max_cpus = - qemu_opt_get_number(opts, "maxcpus", cpus); - - if (ms->smp.max_cpus < cpus) { - error_report("maxcpus must be equal to or greater than smp"); - exit(1); + unsigned cpus = config->has_cpus ? config->cpus : 0; + unsigned sockets = config->has_sockets ? config->sockets : 0; + unsigned dies = config->has_dies ? config->dies : 1; + unsigned cores = config->has_cores ? config->cores : 0; + unsigned threads = config->has_threads ? config->threads : 0; + + /* compute missing values, prefer sockets over cores over threads */ + if (cpus == 0 || sockets == 0) { + cores = cores > 0 ? cores : 1; + threads = threads > 0 ? threads : 1; + if (cpus == 0) { + sockets = sockets > 0 ? sockets : 1; + cpus = cores * threads * dies * sockets; + } else { + ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus; + sockets = ms->smp.max_cpus / (cores * threads * dies); } + } else if (cores == 0) { + threads = threads > 0 ? threads : 1; + cores = cpus / (sockets * dies * threads); + cores = cores > 0 ? cores : 1; + } else if (threads == 0) { + threads = cpus / (cores * dies * sockets); + threads = threads > 0 ? threads : 1; + } else if (sockets * dies * cores * threads < cpus) { + error_setg(errp, "cpu topology: " + "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < " + "smp_cpus (%u)", + sockets, dies, cores, threads, cpus); + return; + } - if (sockets * dies * cores * threads != ms->smp.max_cpus) { - error_report("Invalid CPU topology deprecated: " - "sockets (%u) * dies (%u) * cores (%u) * threads (%u) " - "!= maxcpus (%u)", - sockets, dies, cores, threads, - ms->smp.max_cpus); - exit(1); - } + ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus; - ms->smp.cpus = cpus; - ms->smp.cores = cores; - ms->smp.threads = threads; - ms->smp.sockets = sockets; - x86ms->smp_dies = dies; + if (ms->smp.max_cpus < cpus) { + error_setg(errp, "maxcpus must be equal to or greater than smp"); + return; } - if (ms->smp.cpus > 1) { - Error *blocker = NULL; - error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); - replay_add_blocker(blocker); + if (sockets * dies * cores * threads != ms->smp.max_cpus) { + error_setg(errp, "Invalid CPU topology deprecated: " + "sockets (%u) * dies (%u) * cores (%u) * threads (%u) " + "!= maxcpus (%u)", + sockets, dies, cores, threads, + ms->smp.max_cpus); + return; } + + ms->smp.cpus = cpus; + ms->smp.cores = cores; + ms->smp.threads = threads; + ms->smp.sockets = sockets; + ms->smp.dies = dies; } static diff --git a/hw/i386/x86.c b/hw/i386/x86.c index d30cf27..00448ed 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -64,7 +64,7 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info, { MachineState *ms = MACHINE(x86ms); - topo_info->dies_per_pkg = x86ms->smp_dies; + topo_info->dies_per_pkg = ms->smp.dies; topo_info->cores_per_die = ms->smp.cores; topo_info->threads_per_core = ms->smp.threads; } @@ -293,7 +293,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, init_topo_info(&topo_info, x86ms); - env->nr_dies = x86ms->smp_dies; + env->nr_dies = ms->smp.dies; /* * If APIC ID is not set, @@ -301,13 +301,13 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, */ if (cpu->apic_id == UNASSIGNED_APIC_ID) { int max_socket = (ms->smp.max_cpus - 1) / - smp_threads / smp_cores / x86ms->smp_dies; + smp_threads / smp_cores / ms->smp.dies; /* * die-id was optional in QEMU 4.0 and older, so keep it optional * if there's only one die per socket. */ - if (cpu->die_id < 0 && x86ms->smp_dies == 1) { + if (cpu->die_id < 0 && ms->smp.dies == 1) { cpu->die_id = 0; } @@ -322,9 +322,9 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, if (cpu->die_id < 0) { error_setg(errp, "CPU die-id is not set"); return; - } else if (cpu->die_id > x86ms->smp_dies - 1) { + } else if (cpu->die_id > ms->smp.dies - 1) { error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", - cpu->die_id, x86ms->smp_dies - 1); + cpu->die_id, ms->smp.dies - 1); return; } if (cpu->core_id < 0) { @@ -477,7 +477,7 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) &topo_info, &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) { + if (ms->smp.dies > 1) { ms->possible_cpus->cpus[i].props.has_die_id = true; ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id; } @@ -1269,7 +1269,6 @@ static void x86_machine_initfn(Object *obj) x86ms->smm = ON_OFF_AUTO_AUTO; x86ms->acpi = ON_OFF_AUTO_AUTO; - x86ms->smp_dies = 1; x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS; x86ms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 40e0398..665baf9 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -179,10 +179,12 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len) (r->req.cmd.buf[1] & 0x01)) { page = r->req.cmd.buf[2]; if (page == 0xb0) { - uint32_t max_transfer = - blk_get_max_transfer(s->conf.blk) / s->blocksize; + uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk); + uint32_t max_iov = blk_get_max_iov(s->conf.blk); assert(max_transfer); + max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size) + / s->blocksize; stl_be_p(&r->buf[8], max_transfer); /* Also take care of the opt xfer len. */ stl_be_p(&r->buf[12], diff --git a/hw/usb/meson.build b/hw/usb/meson.build index f357270..4f24b52 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -49,7 +49,7 @@ softmmu_ss.add(when: ['CONFIG_POSIX', 'CONFIG_USB_STORAGE_MTP'], if_true: files( # smartcard softmmu_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader.c')) -if config_host.has_key('CONFIG_SMARTCARD') +if cacard.found() usbsmartcard_ss = ss.source_set() usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: [cacard, files('ccid-card-emulated.c', 'ccid-card-passthru.c')]) @@ -64,7 +64,7 @@ if u2f.found() endif # usb redirect -if config_host.has_key('CONFIG_USB_REDIR') +if usbredir.found() usbredir_ss = ss.source_set() usbredir_ss.add(when: 'CONFIG_USB', if_true: [usbredir, files('redirect.c', 'quirks.c')]) @@ -72,7 +72,7 @@ if config_host.has_key('CONFIG_USB_REDIR') endif # usb pass-through -softmmu_ss.add(when: ['CONFIG_USB', 'CONFIG_USB_LIBUSB', libusb], +softmmu_ss.add(when: ['CONFIG_USB', libusb], if_true: files('host-libusb.c'), if_false: files('host-stub.c')) softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('host-stub.c')) |