mirror of https://github.com/xemu-project/xemu.git
x86 and machine queue, 2019-10-15
Features: * Snowridge-v2 (no MPX) CPU model (Xiaoyao Li) Bug fixes: * cpu-plug-test: fix device_add for pc/q35 machines (Igor Mammedov) * Fix legacy guest with xsave panic on older Linux kernel (Bingsong Si) * Omit all-zeroes entries from KVM CPUID table (Eduardo Habkost) Cleanups: * Convert reset handlers to DeviceReset (Philippe Mathieu-Daudé) * MachineClass::auto_enable_numa field (Tao Xu) * target/i386/cpu.h cleanups (Tao Xu) * memory_device_get_free_addr() cleanups (Wei Yang) -----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEWjIv1avE09usz9GqKAeTb5hNxaYFAl2mO68UHGVoYWJrb3N0 QHJlZGhhdC5jb20ACgkQKAeTb5hNxaafJA//edQTEAo7dD+aPdsvXbTO5aJNdhAI qqllP5L3c9XUlQ39+pfTVs8D5nlo4FG3tuk6VekAkWRyxpdBWvqMKs/a71yuj8ef q5ysUEH8qC9dn4upcaA92M7LZYH0ZFhN9NBZ9VFZp/X3m0WZOooP0OjFLnjP67B5 e4DoZ67gI5aKSZD5iNa/IFcCt4pUqVnJnBGvvytT6indg7TIO+TvPt9z8L5CbZ90 AHXo99BUdM3O8JqPQEZ+O2WRBkbK1K1eHEU5NV5FRGyHIA6LpnK+zwkThgPIwFyE TaAFIr+9l560eXi1uh0zZFIT4ziLgpz2sylDvUC2BeRgJd0nlXhZH+ljQP8F9XR6 tuu0tlScsMODZlWPu305qHnZwPttVLImbJ8egMWMRerTI9hCW0XFzNqTaZn/uWle S8YaSCuBlAVJJFldXtd72lps0z/M/pM4xrdahnyPlrEzSX5x/vrelIed7rAtJZLh IK4UM1Md8iu8E4xIoG8afE9UtekpysLw+zRz3PDKkBKT+VKmdK8wIdAOCFmfRPVp jDRXKLrNrCcxPEuuqvU9xucvV99AZbFHKwTfecoYQe5kssLsi7QJD6p83iofg/Or kFS3eTDpIHb6N9nA70YVjRulYloI/SFKPnRUtge17QIelfuZiEhNUOZlkOld5QCE 8Rgn9fw9tqo/pyQ= =sx0R -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging x86 and machine queue, 2019-10-15 Features: * Snowridge-v2 (no MPX) CPU model (Xiaoyao Li) Bug fixes: * cpu-plug-test: fix device_add for pc/q35 machines (Igor Mammedov) * Fix legacy guest with xsave panic on older Linux kernel (Bingsong Si) * Omit all-zeroes entries from KVM CPUID table (Eduardo Habkost) Cleanups: * Convert reset handlers to DeviceReset (Philippe Mathieu-Daudé) * MachineClass::auto_enable_numa field (Tao Xu) * target/i386/cpu.h cleanups (Tao Xu) * memory_device_get_free_addr() cleanups (Wei Yang) # gpg: Signature made Tue 15 Oct 2019 22:35:43 BST # gpg: using RSA key 5A322FD5ABC4D3DBACCFD1AA2807936F984DC5A6 # gpg: issuer "ehabkost@redhat.com" # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" [full] # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/machine-next-pull-request: target/i386: Add Snowridge-v2 (no MPX) CPU model i386: Omit all-zeroes entries from KVM CPUID table i386: Fix legacy guest with xsave panic on host kvm without update cpuid. target/i386: drop the duplicated definition of cpuid AVX512_VBMI macro target/i386: clean up comments over 80 chars per line memory-device: break the loop if tmp exceed the hinted range memory-device: not necessary to use goto for the last check hw/misc/vmcoreinfo: Add comment about reset handler hw/input/lm832x: Convert reset handler to DeviceReset hw/isa/vt82c686: Convert reset handler to DeviceReset hw/ide/via82c: Convert reset handler to DeviceReset hw/ide/sii3112: Convert reset handler to DeviceReset hw/ide/piix: Convert reset handler to DeviceReset hw/isa/piix4: Convert reset handler to DeviceReset hw/acpi/piix4: Convert reset handler to DeviceReset numa: Introduce MachineClass::auto_enable_numa for implicit NUMA node tests: cpu-plug-test: fix device_add for pc/q35 machines tests: add qtest_qmp_device_add_qdict() helper Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d52932ed34
|
@ -27,7 +27,6 @@
|
|||
#include "hw/pci/pci.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -344,9 +343,9 @@ static const VMStateDescription vmstate_acpi = {
|
|||
}
|
||||
};
|
||||
|
||||
static void piix4_reset(void *opaque)
|
||||
static void piix4_pm_reset(DeviceState *dev)
|
||||
{
|
||||
PIIX4PMState *s = opaque;
|
||||
PIIX4PMState *s = PIIX4_PM(dev);
|
||||
PCIDevice *d = PCI_DEVICE(s);
|
||||
uint8_t *pci_conf = d->config;
|
||||
|
||||
|
@ -542,7 +541,6 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
|
|||
|
||||
s->machine_ready.notify = piix4_pm_machine_ready;
|
||||
qemu_add_machine_init_done_notifier(&s->machine_ready);
|
||||
qemu_register_reset(piix4_reset, s);
|
||||
|
||||
piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
|
||||
pci_get_bus(dev), s);
|
||||
|
@ -692,6 +690,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
|
|||
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
|
||||
k->revision = 0x03;
|
||||
k->class_id = PCI_CLASS_BRIDGE_OTHER;
|
||||
dc->reset = piix4_pm_reset;
|
||||
dc->desc = "PM";
|
||||
dc->vmsd = &vmstate_acpi;
|
||||
dc->props = piix4_pm_properties;
|
||||
|
|
|
@ -378,11 +378,17 @@ void numa_complete_configuration(MachineState *ms)
|
|||
* guest tries to use it with that drivers.
|
||||
*
|
||||
* Enable NUMA implicitly by adding a new NUMA node automatically.
|
||||
*
|
||||
* Or if MachineClass::auto_enable_numa is true and no NUMA nodes,
|
||||
* assume there is just one node with whole RAM.
|
||||
*/
|
||||
if (ms->ram_slots > 0 && ms->numa_state->num_nodes == 0 &&
|
||||
mc->auto_enable_numa_with_memhp) {
|
||||
if (ms->numa_state->num_nodes == 0 &&
|
||||
((ms->ram_slots > 0 &&
|
||||
mc->auto_enable_numa_with_memhp) ||
|
||||
mc->auto_enable_numa)) {
|
||||
NumaNodeOptions node = { };
|
||||
parse_numa_node(ms, &node, &error_abort);
|
||||
numa_info[0].node_mem = ram_size;
|
||||
}
|
||||
|
||||
assert(max_numa_nodeid <= MAX_NODES);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "sysemu/reset.h"
|
||||
|
||||
#include "hw/ide/pci.h"
|
||||
#include "trace.h"
|
||||
|
@ -103,9 +102,9 @@ static void bmdma_setup_bar(PCIIDEState *d)
|
|||
}
|
||||
}
|
||||
|
||||
static void piix3_reset(void *opaque)
|
||||
static void piix_ide_reset(DeviceState *dev)
|
||||
{
|
||||
PCIIDEState *d = opaque;
|
||||
PCIIDEState *d = PCI_IDE(dev);
|
||||
PCIDevice *pd = PCI_DEVICE(d);
|
||||
uint8_t *pci_conf = pd->config;
|
||||
int i;
|
||||
|
@ -154,8 +153,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
|
|||
|
||||
pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
|
||||
|
||||
qemu_register_reset(piix3_reset, d);
|
||||
|
||||
bmdma_setup_bar(d);
|
||||
pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
|
||||
|
||||
|
@ -247,6 +244,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = piix_ide_reset;
|
||||
k->realize = pci_piix_ide_realize;
|
||||
k->exit = pci_piix_ide_exitfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
|
@ -273,6 +271,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = piix_ide_reset;
|
||||
k->realize = pci_piix_ide_realize;
|
||||
k->exit = pci_piix_ide_exitfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "hw/ide/pci.h"
|
||||
#include "qemu/module.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define TYPE_SII3112_PCI "sii3112"
|
||||
|
@ -237,9 +236,9 @@ static void sii3112_set_irq(void *opaque, int channel, int level)
|
|||
sii3112_update_irq(s);
|
||||
}
|
||||
|
||||
static void sii3112_reset(void *opaque)
|
||||
static void sii3112_reset(DeviceState *dev)
|
||||
{
|
||||
SiI3112PCIState *s = opaque;
|
||||
SiI3112PCIState *s = SII3112_PCI(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
@ -290,7 +289,6 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
|
|||
s->bmdma[i].bus = &s->bus[i];
|
||||
ide_register_restart_cb(&s->bus[i]);
|
||||
}
|
||||
qemu_register_reset(sii3112_reset, s);
|
||||
}
|
||||
|
||||
static void sii3112_pci_class_init(ObjectClass *klass, void *data)
|
||||
|
@ -303,6 +301,7 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
|
|||
pd->class_id = PCI_CLASS_STORAGE_RAID;
|
||||
pd->revision = 1;
|
||||
pd->realize = sii3112_pci_realize;
|
||||
dc->reset = sii3112_reset;
|
||||
dc->desc = "SiI3112A SATA controller";
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
}
|
||||
|
|
10
hw/ide/via.c
10
hw/ide/via.c
|
@ -29,7 +29,6 @@
|
|||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "sysemu/reset.h"
|
||||
|
||||
#include "hw/ide/pci.h"
|
||||
#include "trace.h"
|
||||
|
@ -120,10 +119,10 @@ static void via_ide_set_irq(void *opaque, int n, int level)
|
|||
}
|
||||
}
|
||||
|
||||
static void via_ide_reset(void *opaque)
|
||||
static void via_ide_reset(DeviceState *dev)
|
||||
{
|
||||
PCIIDEState *d = opaque;
|
||||
PCIDevice *pd = PCI_DEVICE(d);
|
||||
PCIIDEState *d = PCI_IDE(dev);
|
||||
PCIDevice *pd = PCI_DEVICE(dev);
|
||||
uint8_t *pci_conf = pd->config;
|
||||
int i;
|
||||
|
||||
|
@ -172,8 +171,6 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
|
|||
pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
|
||||
dev->wmask[PCI_INTERRUPT_LINE] = 0xf;
|
||||
|
||||
qemu_register_reset(via_ide_reset, d);
|
||||
|
||||
memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
|
||||
&d->bus[0], "via-ide0-data", 8);
|
||||
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
|
||||
|
@ -229,6 +226,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = via_ide_reset;
|
||||
k->realize = via_ide_realize;
|
||||
k->exit = via_ide_exitfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_VIA;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "ui/console.h"
|
||||
|
||||
#define TYPE_LM8323 "lm8323"
|
||||
|
@ -94,8 +93,10 @@ static void lm_kbd_gpio_update(LM823KbdState *s)
|
|||
{
|
||||
}
|
||||
|
||||
static void lm_kbd_reset(LM823KbdState *s)
|
||||
static void lm_kbd_reset(DeviceState *dev)
|
||||
{
|
||||
LM823KbdState *s = LM8323(dev);
|
||||
|
||||
s->config = 0x80;
|
||||
s->status = INT_NOINIT;
|
||||
s->acttime = 125;
|
||||
|
@ -273,7 +274,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
|
|||
|
||||
case LM832x_CMD_RESET:
|
||||
if (value == 0xaa)
|
||||
lm_kbd_reset(s);
|
||||
lm_kbd_reset(DEVICE(s));
|
||||
else
|
||||
lm_kbd_error(s, ERR_BADPAR);
|
||||
s->reg = LM832x_GENERAL_ERROR;
|
||||
|
@ -476,10 +477,6 @@ static void lm8323_realize(DeviceState *dev, Error **errp)
|
|||
s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
|
||||
s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
|
||||
qdev_init_gpio_out(dev, &s->nirq, 1);
|
||||
|
||||
lm_kbd_reset(s);
|
||||
|
||||
qemu_register_reset((void *) lm_kbd_reset, s);
|
||||
}
|
||||
|
||||
void lm832x_key_event(DeviceState *dev, int key, int state)
|
||||
|
@ -507,6 +504,7 @@ static void lm8323_class_init(ObjectClass *klass, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
dc->reset = lm_kbd_reset;
|
||||
dc->realize = lm8323_realize;
|
||||
k->event = lm_i2c_event;
|
||||
k->recv = lm_i2c_rx;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "hw/isa/isa.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "sysemu/reset.h"
|
||||
|
||||
PCIDevice *piix4_dev;
|
||||
|
||||
|
@ -40,9 +39,9 @@ typedef struct PIIX4State {
|
|||
#define PIIX4_PCI_DEVICE(obj) \
|
||||
OBJECT_CHECK(PIIX4State, (obj), TYPE_PIIX4_PCI_DEVICE)
|
||||
|
||||
static void piix4_reset(void *opaque)
|
||||
static void piix4_isa_reset(DeviceState *dev)
|
||||
{
|
||||
PIIX4State *d = opaque;
|
||||
PIIX4State *d = PIIX4_PCI_DEVICE(dev);
|
||||
uint8_t *pci_conf = d->dev.config;
|
||||
|
||||
pci_conf[0x04] = 0x07; // master, memory and I/O
|
||||
|
@ -97,7 +96,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
piix4_dev = &d->dev;
|
||||
qemu_register_reset(piix4_reset, d);
|
||||
}
|
||||
|
||||
int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
|
||||
|
@ -118,6 +116,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
|
|||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
|
||||
k->class_id = PCI_CLASS_BRIDGE_ISA;
|
||||
dc->reset = piix4_isa_reset;
|
||||
dc->desc = "ISA bridge";
|
||||
dc->vmsd = &vmstate_piix4;
|
||||
/*
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "hw/isa/apm.h"
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "hw/i2c/pm_smbus.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "exec/address-spaces.h"
|
||||
|
@ -116,11 +115,10 @@ static const MemoryRegionOps superio_ops = {
|
|||
},
|
||||
};
|
||||
|
||||
static void vt82c686b_reset(void * opaque)
|
||||
static void vt82c686b_isa_reset(DeviceState *dev)
|
||||
{
|
||||
PCIDevice *d = opaque;
|
||||
uint8_t *pci_conf = d->config;
|
||||
VT82C686BState *vt82c = VT82C686B_DEVICE(d);
|
||||
VT82C686BState *vt82c = VT82C686B_DEVICE(dev);
|
||||
uint8_t *pci_conf = vt82c->dev.config;
|
||||
|
||||
pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
|
||||
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
|
||||
|
@ -476,8 +474,6 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
|
|||
* But we do not emulate a floppy, so just set it here. */
|
||||
memory_region_add_subregion(isa_bus->address_space_io, 0x3f0,
|
||||
&vt82c->superio);
|
||||
|
||||
qemu_register_reset(vt82c686b_reset, d);
|
||||
}
|
||||
|
||||
ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn)
|
||||
|
@ -501,6 +497,7 @@ static void via_class_init(ObjectClass *klass, void *data)
|
|||
k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
|
||||
k->class_id = PCI_CLASS_BRIDGE_ISA;
|
||||
k->revision = 0x40;
|
||||
dc->reset = vt82c686b_isa_reset;
|
||||
dc->desc = "ISA bridge";
|
||||
dc->vmsd = &vmstate_via;
|
||||
/*
|
||||
|
|
|
@ -179,13 +179,14 @@ static uint64_t memory_device_get_free_addr(MachineState *ms,
|
|||
range_make_empty(&new);
|
||||
break;
|
||||
}
|
||||
} else if (range_lob(&tmp) > range_upb(&new)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!range_contains_range(&as, &new)) {
|
||||
error_setg(errp, "could not find position in guest address space for "
|
||||
"memory device - memory fragmented due to alignments");
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
g_slist_free(list);
|
||||
|
|
|
@ -61,6 +61,10 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
|
|||
NULL, fw_cfg_vmci_write, s,
|
||||
&s->vmcoreinfo, sizeof(s->vmcoreinfo), false);
|
||||
|
||||
/*
|
||||
* This device requires to register a global reset because it is
|
||||
* not plugged to a bus (which, as its QOM parent, would reset it).
|
||||
*/
|
||||
qemu_register_reset(vmcoreinfo_reset, dev);
|
||||
vmcoreinfo_state = s;
|
||||
}
|
||||
|
|
|
@ -346,14 +346,6 @@ static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt)
|
|||
hwaddr mem_start, node_size;
|
||||
int i, nb_nodes = machine->numa_state->num_nodes;
|
||||
NodeInfo *nodes = machine->numa_state->nodes;
|
||||
NodeInfo ramnode;
|
||||
|
||||
/* No NUMA nodes, assume there is just one node with whole RAM */
|
||||
if (!nb_nodes) {
|
||||
nb_nodes = 1;
|
||||
ramnode.node_mem = machine->ram_size;
|
||||
nodes = &ramnode;
|
||||
}
|
||||
|
||||
for (i = 0, mem_start = 0; i < nb_nodes; ++i) {
|
||||
if (!nodes[i].node_mem) {
|
||||
|
@ -4430,6 +4422,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|||
*/
|
||||
mc->numa_mem_align_shift = 28;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->auto_enable_numa = true;
|
||||
|
||||
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
|
||||
smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
|
||||
|
|
|
@ -228,6 +228,7 @@ struct MachineClass {
|
|||
bool smbus_no_migration_support;
|
||||
bool nvdimm_supported;
|
||||
bool numa_mem_supported;
|
||||
bool auto_enable_numa;
|
||||
|
||||
HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
|
||||
DeviceState *dev);
|
||||
|
|
|
@ -2645,8 +2645,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
|
||||
CPUID_7_0_EBX_SMAP,
|
||||
.features[FEAT_7_0_ECX] =
|
||||
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
|
||||
CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
|
||||
CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
|
||||
CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
|
||||
CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
|
||||
CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
|
||||
CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
|
||||
|
@ -2703,8 +2703,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
|
||||
CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
|
||||
.features[FEAT_7_0_ECX] =
|
||||
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
|
||||
CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
|
||||
CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
|
||||
CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
|
||||
CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
|
||||
CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
|
||||
CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
|
||||
|
@ -2793,6 +2793,18 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||
CPUID_6_EAX_ARAT,
|
||||
.xlevel = 0x80000008,
|
||||
.model_id = "Intel Atom Processor (SnowRidge)",
|
||||
.versions = (X86CPUVersionDefinition[]) {
|
||||
{ .version = 1 },
|
||||
{
|
||||
.version = 2,
|
||||
.props = (PropValue[]) {
|
||||
{ "mpx", "off" },
|
||||
{ "model-id", "Intel Atom Processor (Snowridge, no MPX)" },
|
||||
{ /* end of list */ },
|
||||
},
|
||||
},
|
||||
{ /* end of list */ },
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "KnightsMill",
|
||||
|
@ -4693,7 +4705,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|||
*ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
|
||||
*eax = env->features[FEAT_XSAVE_COMP_LO];
|
||||
*edx = env->features[FEAT_XSAVE_COMP_HI];
|
||||
*ebx = xsave_area_size(env->xcr0);
|
||||
/*
|
||||
* The initial value of xcr0 and ebx == 0, On host without kvm
|
||||
* commit 412a3c41(e.g., CentOS 6), the ebx's value always == 0
|
||||
* even through guest update xcr0, this will crash some legacy guest
|
||||
* (e.g., CentOS 6), So set ebx == ecx to workaroud it.
|
||||
*/
|
||||
*ebx = kvm_enabled() ? *ecx : xsave_area_size(env->xcr0);
|
||||
} else if (count == 1) {
|
||||
*eax = env->features[FEAT_XSAVE];
|
||||
} else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
|
||||
|
|
|
@ -669,65 +669,116 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
|||
#define CPUID_SVM_PAUSEFILTER (1U << 10)
|
||||
#define CPUID_SVM_PFTHRESHOLD (1U << 12)
|
||||
|
||||
#define CPUID_7_0_EBX_FSGSBASE (1U << 0)
|
||||
#define CPUID_7_0_EBX_BMI1 (1U << 3)
|
||||
#define CPUID_7_0_EBX_HLE (1U << 4)
|
||||
#define CPUID_7_0_EBX_AVX2 (1U << 5)
|
||||
#define CPUID_7_0_EBX_SMEP (1U << 7)
|
||||
#define CPUID_7_0_EBX_BMI2 (1U << 8)
|
||||
#define CPUID_7_0_EBX_ERMS (1U << 9)
|
||||
#define CPUID_7_0_EBX_INVPCID (1U << 10)
|
||||
#define CPUID_7_0_EBX_RTM (1U << 11)
|
||||
#define CPUID_7_0_EBX_MPX (1U << 14)
|
||||
#define CPUID_7_0_EBX_AVX512F (1U << 16) /* AVX-512 Foundation */
|
||||
#define CPUID_7_0_EBX_AVX512DQ (1U << 17) /* AVX-512 Doubleword & Quadword Instrs */
|
||||
#define CPUID_7_0_EBX_RDSEED (1U << 18)
|
||||
#define CPUID_7_0_EBX_ADX (1U << 19)
|
||||
#define CPUID_7_0_EBX_SMAP (1U << 20)
|
||||
#define CPUID_7_0_EBX_AVX512IFMA (1U << 21) /* AVX-512 Integer Fused Multiply Add */
|
||||
#define CPUID_7_0_EBX_PCOMMIT (1U << 22) /* Persistent Commit */
|
||||
#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) /* Flush a Cache Line Optimized */
|
||||
#define CPUID_7_0_EBX_CLWB (1U << 24) /* Cache Line Write Back */
|
||||
#define CPUID_7_0_EBX_INTEL_PT (1U << 25) /* Intel Processor Trace */
|
||||
#define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */
|
||||
#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
|
||||
#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
|
||||
#define CPUID_7_0_EBX_SHA_NI (1U << 29) /* SHA1/SHA256 Instruction Extensions */
|
||||
#define CPUID_7_0_EBX_AVX512BW (1U << 30) /* AVX-512 Byte and Word Instructions */
|
||||
#define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Length Extensions */
|
||||
/* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
|
||||
#define CPUID_7_0_EBX_FSGSBASE (1U << 0)
|
||||
/* 1st Group of Advanced Bit Manipulation Extensions */
|
||||
#define CPUID_7_0_EBX_BMI1 (1U << 3)
|
||||
/* Hardware Lock Elision */
|
||||
#define CPUID_7_0_EBX_HLE (1U << 4)
|
||||
/* Intel Advanced Vector Extensions 2 */
|
||||
#define CPUID_7_0_EBX_AVX2 (1U << 5)
|
||||
/* Supervisor-mode Execution Prevention */
|
||||
#define CPUID_7_0_EBX_SMEP (1U << 7)
|
||||
/* 2nd Group of Advanced Bit Manipulation Extensions */
|
||||
#define CPUID_7_0_EBX_BMI2 (1U << 8)
|
||||
/* Enhanced REP MOVSB/STOSB */
|
||||
#define CPUID_7_0_EBX_ERMS (1U << 9)
|
||||
/* Invalidate Process-Context Identifier */
|
||||
#define CPUID_7_0_EBX_INVPCID (1U << 10)
|
||||
/* Restricted Transactional Memory */
|
||||
#define CPUID_7_0_EBX_RTM (1U << 11)
|
||||
/* Memory Protection Extension */
|
||||
#define CPUID_7_0_EBX_MPX (1U << 14)
|
||||
/* AVX-512 Foundation */
|
||||
#define CPUID_7_0_EBX_AVX512F (1U << 16)
|
||||
/* AVX-512 Doubleword & Quadword Instruction */
|
||||
#define CPUID_7_0_EBX_AVX512DQ (1U << 17)
|
||||
/* Read Random SEED */
|
||||
#define CPUID_7_0_EBX_RDSEED (1U << 18)
|
||||
/* ADCX and ADOX instructions */
|
||||
#define CPUID_7_0_EBX_ADX (1U << 19)
|
||||
/* Supervisor Mode Access Prevention */
|
||||
#define CPUID_7_0_EBX_SMAP (1U << 20)
|
||||
/* AVX-512 Integer Fused Multiply Add */
|
||||
#define CPUID_7_0_EBX_AVX512IFMA (1U << 21)
|
||||
/* Persistent Commit */
|
||||
#define CPUID_7_0_EBX_PCOMMIT (1U << 22)
|
||||
/* Flush a Cache Line Optimized */
|
||||
#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23)
|
||||
/* Cache Line Write Back */
|
||||
#define CPUID_7_0_EBX_CLWB (1U << 24)
|
||||
/* Intel Processor Trace */
|
||||
#define CPUID_7_0_EBX_INTEL_PT (1U << 25)
|
||||
/* AVX-512 Prefetch */
|
||||
#define CPUID_7_0_EBX_AVX512PF (1U << 26)
|
||||
/* AVX-512 Exponential and Reciprocal */
|
||||
#define CPUID_7_0_EBX_AVX512ER (1U << 27)
|
||||
/* AVX-512 Conflict Detection */
|
||||
#define CPUID_7_0_EBX_AVX512CD (1U << 28)
|
||||
/* SHA1/SHA256 Instruction Extensions */
|
||||
#define CPUID_7_0_EBX_SHA_NI (1U << 29)
|
||||
/* AVX-512 Byte and Word Instructions */
|
||||
#define CPUID_7_0_EBX_AVX512BW (1U << 30)
|
||||
/* AVX-512 Vector Length Extensions */
|
||||
#define CPUID_7_0_EBX_AVX512VL (1U << 31)
|
||||
|
||||
#define CPUID_7_0_ECX_AVX512BMI (1U << 1)
|
||||
#define CPUID_7_0_ECX_VBMI (1U << 1) /* AVX-512 Vector Byte Manipulation Instrs */
|
||||
#define CPUID_7_0_ECX_UMIP (1U << 2)
|
||||
#define CPUID_7_0_ECX_PKU (1U << 3)
|
||||
#define CPUID_7_0_ECX_OSPKE (1U << 4)
|
||||
#define CPUID_7_0_ECX_VBMI2 (1U << 6) /* Additional VBMI Instrs */
|
||||
#define CPUID_7_0_ECX_GFNI (1U << 8)
|
||||
#define CPUID_7_0_ECX_VAES (1U << 9)
|
||||
#define CPUID_7_0_ECX_VPCLMULQDQ (1U << 10)
|
||||
#define CPUID_7_0_ECX_AVX512VNNI (1U << 11)
|
||||
#define CPUID_7_0_ECX_AVX512BITALG (1U << 12)
|
||||
#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) /* POPCNT for vectors of DW/QW */
|
||||
#define CPUID_7_0_ECX_LA57 (1U << 16)
|
||||
#define CPUID_7_0_ECX_RDPID (1U << 22)
|
||||
#define CPUID_7_0_ECX_CLDEMOTE (1U << 25) /* CLDEMOTE Instruction */
|
||||
#define CPUID_7_0_ECX_MOVDIRI (1U << 27) /* MOVDIRI Instruction */
|
||||
#define CPUID_7_0_ECX_MOVDIR64B (1U << 28) /* MOVDIR64B Instruction */
|
||||
/* AVX-512 Vector Byte Manipulation Instruction */
|
||||
#define CPUID_7_0_ECX_AVX512_VBMI (1U << 1)
|
||||
/* User-Mode Instruction Prevention */
|
||||
#define CPUID_7_0_ECX_UMIP (1U << 2)
|
||||
/* Protection Keys for User-mode Pages */
|
||||
#define CPUID_7_0_ECX_PKU (1U << 3)
|
||||
/* OS Enable Protection Keys */
|
||||
#define CPUID_7_0_ECX_OSPKE (1U << 4)
|
||||
/* Additional AVX-512 Vector Byte Manipulation Instruction */
|
||||
#define CPUID_7_0_ECX_AVX512_VBMI2 (1U << 6)
|
||||
/* Galois Field New Instructions */
|
||||
#define CPUID_7_0_ECX_GFNI (1U << 8)
|
||||
/* Vector AES Instructions */
|
||||
#define CPUID_7_0_ECX_VAES (1U << 9)
|
||||
/* Carry-Less Multiplication Quadword */
|
||||
#define CPUID_7_0_ECX_VPCLMULQDQ (1U << 10)
|
||||
/* Vector Neural Network Instructions */
|
||||
#define CPUID_7_0_ECX_AVX512VNNI (1U << 11)
|
||||
/* Support for VPOPCNT[B,W] and VPSHUFBITQMB */
|
||||
#define CPUID_7_0_ECX_AVX512BITALG (1U << 12)
|
||||
/* POPCNT for vectors of DW/QW */
|
||||
#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14)
|
||||
/* 5-level Page Tables */
|
||||
#define CPUID_7_0_ECX_LA57 (1U << 16)
|
||||
/* Read Processor ID */
|
||||
#define CPUID_7_0_ECX_RDPID (1U << 22)
|
||||
/* Cache Line Demote Instruction */
|
||||
#define CPUID_7_0_ECX_CLDEMOTE (1U << 25)
|
||||
/* Move Doubleword as Direct Store Instruction */
|
||||
#define CPUID_7_0_ECX_MOVDIRI (1U << 27)
|
||||
/* Move 64 Bytes as Direct Store Instruction */
|
||||
#define CPUID_7_0_ECX_MOVDIR64B (1U << 28)
|
||||
|
||||
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */
|
||||
#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
|
||||
#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
|
||||
#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) /*Arch Capabilities*/
|
||||
#define CPUID_7_0_EDX_CORE_CAPABILITY (1U << 30) /*Core Capability*/
|
||||
#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */
|
||||
/* AVX512 Neural Network Instructions */
|
||||
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2)
|
||||
/* AVX512 Multiply Accumulation Single Precision */
|
||||
#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3)
|
||||
/* Speculation Control */
|
||||
#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26)
|
||||
/* Arch Capabilities */
|
||||
#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)
|
||||
/* Core Capability */
|
||||
#define CPUID_7_0_EDX_CORE_CAPABILITY (1U << 30)
|
||||
/* Speculative Store Bypass Disable */
|
||||
#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31)
|
||||
|
||||
#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) /* AVX512 BFloat16 Instruction */
|
||||
/* AVX512 BFloat16 Instruction */
|
||||
#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5)
|
||||
|
||||
#define CPUID_8000_0008_EBX_CLZERO (1U << 0) /* CLZERO instruction */
|
||||
#define CPUID_8000_0008_EBX_XSAVEERPTR (1U << 2) /* Always save/restore FP error pointers */
|
||||
#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9) /* Write back and
|
||||
do not invalidate cache */
|
||||
#define CPUID_8000_0008_EBX_IBPB (1U << 12) /* Indirect Branch Prediction Barrier */
|
||||
/* CLZERO instruction */
|
||||
#define CPUID_8000_0008_EBX_CLZERO (1U << 0)
|
||||
/* Always save/restore FP error pointers */
|
||||
#define CPUID_8000_0008_EBX_XSAVEERPTR (1U << 2)
|
||||
/* Write back and do not invalidate cache */
|
||||
#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9)
|
||||
/* Indirect Branch Prediction Barrier */
|
||||
#define CPUID_8000_0008_EBX_IBPB (1U << 12)
|
||||
|
||||
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
|
||||
#define CPUID_XSAVE_XSAVEC (1U << 1)
|
||||
|
|
|
@ -89,7 +89,7 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
|
|||
ebx &= ~CPUID_7_0_EBX_INVPCID;
|
||||
}
|
||||
|
||||
ecx &= CPUID_7_0_ECX_AVX512BMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ;
|
||||
ecx &= CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ;
|
||||
edx &= CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS;
|
||||
} else {
|
||||
ebx = 0;
|
||||
|
|
|
@ -1567,6 +1567,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||
c->function = i;
|
||||
c->flags = 0;
|
||||
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||
if (!c->eax && !c->ebx && !c->ecx && !c->edx) {
|
||||
/*
|
||||
* KVM already returns all zeroes if a CPUID entry is missing,
|
||||
* so we can omit it and avoid hitting KVM's 80-entry limit.
|
||||
*/
|
||||
cpuid_i--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1631,6 +1638,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||
c->function = i;
|
||||
c->flags = 0;
|
||||
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||
if (!c->eax && !c->ebx && !c->ecx && !c->edx) {
|
||||
/*
|
||||
* KVM already returns all zeroes if a CPUID entry is missing,
|
||||
* so we can omit it and avoid hitting KVM's 80-entry limit.
|
||||
*/
|
||||
cpuid_i--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "libqtest-single.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
|
||||
struct PlugTestData {
|
||||
char *machine;
|
||||
|
@ -72,12 +73,15 @@ static void test_plug_without_cpu_add(gconstpointer data)
|
|||
g_free(args);
|
||||
}
|
||||
|
||||
static void test_plug_with_device_add_x86(gconstpointer data)
|
||||
static void test_plug_with_device_add(gconstpointer data)
|
||||
{
|
||||
const PlugTestData *td = data;
|
||||
char *args;
|
||||
unsigned int s, c, t;
|
||||
QTestState *qts;
|
||||
QDict *resp;
|
||||
QList *cpus;
|
||||
QObject *e;
|
||||
int hotplugged = 0;
|
||||
|
||||
args = g_strdup_printf("-machine %s -cpu %s "
|
||||
"-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
|
||||
|
@ -85,43 +89,29 @@ static void test_plug_with_device_add_x86(gconstpointer data)
|
|||
td->sockets, td->cores, td->threads, td->maxcpus);
|
||||
qts = qtest_init(args);
|
||||
|
||||
for (s = 1; s < td->sockets; s++) {
|
||||
for (c = 0; c < td->cores; c++) {
|
||||
for (t = 0; t < td->threads; t++) {
|
||||
char *id = g_strdup_printf("id-%i-%i-%i", s, c, t);
|
||||
qtest_qmp_device_add(qts, td->device_model, id,
|
||||
"{'socket-id':%u, 'core-id':%u,"
|
||||
" 'thread-id':%u}",
|
||||
s, c, t);
|
||||
g_free(id);
|
||||
}
|
||||
resp = qtest_qmp(qts, "{ 'execute': 'query-hotpluggable-cpus'}");
|
||||
g_assert(qdict_haskey(resp, "return"));
|
||||
cpus = qdict_get_qlist(resp, "return");
|
||||
g_assert(cpus);
|
||||
|
||||
while ((e = qlist_pop(cpus))) {
|
||||
const QDict *cpu, *props;
|
||||
|
||||
cpu = qobject_to(QDict, e);
|
||||
if (qdict_haskey(cpu, "qom-path")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g_assert(qdict_haskey(cpu, "props"));
|
||||
props = qdict_get_qdict(cpu, "props");
|
||||
|
||||
qtest_qmp_device_add_qdict(qts, td->device_model, props);
|
||||
hotplugged++;
|
||||
}
|
||||
|
||||
qtest_quit(qts);
|
||||
g_free(args);
|
||||
}
|
||||
|
||||
static void test_plug_with_device_add_coreid(gconstpointer data)
|
||||
{
|
||||
const PlugTestData *td = data;
|
||||
char *args;
|
||||
unsigned int c;
|
||||
QTestState *qts;
|
||||
|
||||
args = g_strdup_printf("-machine %s -cpu %s "
|
||||
"-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
|
||||
td->machine, td->cpu_model,
|
||||
td->sockets, td->cores, td->threads, td->maxcpus);
|
||||
qts = qtest_init(args);
|
||||
|
||||
for (c = 1; c < td->cores; c++) {
|
||||
char *id = g_strdup_printf("id-%i", c);
|
||||
qtest_qmp_device_add(qts, td->device_model, id,
|
||||
"{'core-id':%u}", c);
|
||||
g_free(id);
|
||||
}
|
||||
|
||||
/* make sure that there were hotplugged CPUs */
|
||||
g_assert(hotplugged);
|
||||
qobject_unref(resp);
|
||||
qtest_quit(qts);
|
||||
g_free(args);
|
||||
}
|
||||
|
@ -182,7 +172,7 @@ static void add_pc_test_case(const char *mname)
|
|||
path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
|
||||
mname, data2->sockets, data2->cores,
|
||||
data2->threads, data2->maxcpus);
|
||||
qtest_add_data_func_full(path, data2, test_plug_with_device_add_x86,
|
||||
qtest_add_data_func_full(path, data2, test_plug_with_device_add,
|
||||
test_data_free);
|
||||
g_free(path);
|
||||
}
|
||||
|
@ -209,7 +199,7 @@ static void add_pseries_test_case(const char *mname)
|
|||
path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
|
||||
mname, data->sockets, data->cores,
|
||||
data->threads, data->maxcpus);
|
||||
qtest_add_data_func_full(path, data, test_plug_with_device_add_coreid,
|
||||
qtest_add_data_func_full(path, data, test_plug_with_device_add,
|
||||
test_data_free);
|
||||
g_free(path);
|
||||
}
|
||||
|
@ -246,7 +236,7 @@ static void add_s390x_test_case(const char *mname)
|
|||
path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
|
||||
mname, data2->sockets, data2->cores,
|
||||
data2->threads, data2->maxcpus);
|
||||
qtest_add_data_func_full(path, data2, test_plug_with_device_add_coreid,
|
||||
qtest_add_data_func_full(path, data2, test_plug_with_device_add,
|
||||
test_data_free);
|
||||
g_free(path);
|
||||
}
|
||||
|
|
|
@ -1243,28 +1243,37 @@ QDict *qtest_qmp_receive_success(QTestState *s,
|
|||
}
|
||||
|
||||
/*
|
||||
* Generic hot-plugging test via the device_add QMP command.
|
||||
* Generic hot-plugging test via the device_add QMP commands.
|
||||
*/
|
||||
void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv,
|
||||
const QDict *arguments)
|
||||
{
|
||||
QDict *resp;
|
||||
QDict *args = arguments ? qdict_clone_shallow(arguments) : qdict_new();
|
||||
|
||||
g_assert(!qdict_haskey(args, "driver"));
|
||||
qdict_put_str(args, "driver", drv);
|
||||
resp = qtest_qmp(qts, "{'execute': 'device_add', 'arguments': %p}", args);
|
||||
g_assert(resp);
|
||||
g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */
|
||||
g_assert(!qdict_haskey(resp, "error"));
|
||||
qobject_unref(resp);
|
||||
}
|
||||
|
||||
void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
QDict *args, *response;
|
||||
QDict *args;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
args = qdict_from_vjsonf_nofail(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
g_assert(!qdict_haskey(args, "driver") && !qdict_haskey(args, "id"));
|
||||
qdict_put_str(args, "driver", driver);
|
||||
g_assert(!qdict_haskey(args, "id"));
|
||||
qdict_put_str(args, "id", id);
|
||||
|
||||
response = qtest_qmp(qts, "{'execute': 'device_add', 'arguments': %p}",
|
||||
args);
|
||||
g_assert(response);
|
||||
g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */
|
||||
g_assert(!qdict_haskey(response, "error"));
|
||||
qobject_unref(response);
|
||||
qtest_qmp_device_add_qdict(qts, driver, args);
|
||||
}
|
||||
|
||||
static void device_deleted_cb(void *opaque, const char *name, QDict *data)
|
||||
|
|
|
@ -659,6 +659,18 @@ QDict *qmp_fd(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
|||
void qtest_cb_for_every_machine(void (*cb)(const char *machine),
|
||||
bool skip_old_versioned);
|
||||
|
||||
/**
|
||||
* qtest_qmp_device_add_qdict:
|
||||
* @qts: QTestState instance to operate on
|
||||
* @drv: Name of the device that should be added
|
||||
* @arguments: QDict with properties for the device to intialize
|
||||
*
|
||||
* Generic hot-plugging test via the device_add QMP command with properties
|
||||
* supplied in form of QDict. Use NULL for empty properties list.
|
||||
*/
|
||||
void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv,
|
||||
const QDict *arguments);
|
||||
|
||||
/**
|
||||
* qtest_qmp_device_add:
|
||||
* @qts: QTestState instance to operate on
|
||||
|
|
Loading…
Reference in New Issue