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:
Peter Maydell 2019-10-17 18:16:55 +01:00
commit d52932ed34
19 changed files with 246 additions and 158 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
/*

View File

@ -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;
/*

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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)) {

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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