Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into sta…
Browse files Browse the repository at this point in the history
…ging

pc,virtio,pci: fixes, tests

Fixes all over the place, a new test.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Tue 23 Feb 2021 16:00:29 GMT
# gpg:                using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469
# gpg:                issuer "mst@redhat.com"
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full]
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>" [full]
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  qtest/acpi/bios-tables-test: update acpi tables
  acpi: add test case for -no-hpet
  i386: acpi: Don't build HPET ACPI entry if HPET is disabled
  hw/i386: declare ACPI mother board resource for MMCONFIG region
  acpi: add test case for smm unsupported -machine smm=off
  acpi: set fadt.smi_cmd to zero when SMM is not supported
  acpi/core: always set SCI_EN when SMM isn't supported
  ich9, piix4: add property, smm-compat, to keep compatibility of SMM
  qtest: update tests/qtest/bios-tables-test-allowed-diff.h
  checkpatch: don't emit warning on newly created acpi data files
  tests/data/acpi/virt/DSDT.pxb: update with _CCA
  acpi/gpex: Fix cca attribute check for pxb device
  acpi: Allow pxb DSDT acpi table changes
  pcie: don't set link state active if the slot is empty
  failover: really display a warning when the primary device is not found
  virtio-net: add missing object_unref()
  pci: cleanup failover sanity check

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Feb 25, 2021
2 parents 7ef8134 + 7b630d9 commit 51db2d7
Show file tree
Hide file tree
Showing 30 changed files with 215 additions and 36 deletions.
11 changes: 10 additions & 1 deletion hw/acpi/core.c
Expand Up @@ -579,6 +579,10 @@ void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable)
{
/* ACPI specs 3.0, 4.7.2.5 */
if (ar->pm1.cnt.acpi_only) {
return;
}

if (sci_enable) {
ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
} else if (sci_disable) {
Expand Down Expand Up @@ -608,11 +612,13 @@ static const MemoryRegionOps acpi_pm_cnt_ops = {
};

void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
bool disable_s3, bool disable_s4, uint8_t s4_val)
bool disable_s3, bool disable_s4, uint8_t s4_val,
bool acpi_only)
{
FWCfgState *fw_cfg;

ar->pm1.cnt.s4_val = s4_val;
ar->pm1.cnt.acpi_only = acpi_only;
ar->wakeup.notify = acpi_notify_wakeup;
qemu_register_wakeup_notifier(&ar->wakeup);

Expand All @@ -638,6 +644,9 @@ void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
void acpi_pm1_cnt_reset(ACPIREGS *ar)
{
ar->pm1.cnt.cnt = 0;
if (ar->pm1.cnt.acpi_only) {
ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
}
}

/* ACPI GPE */
Expand Down
2 changes: 1 addition & 1 deletion hw/acpi/ich9.c
Expand Up @@ -282,7 +282,7 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->disable_s3, pm->disable_s4,
pm->s4_val);
pm->s4_val, !pm->smm_compat && !smm_enabled);

acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
Expand Down
5 changes: 4 additions & 1 deletion hw/acpi/piix4.c
Expand Up @@ -74,6 +74,7 @@ struct PIIX4PMState {
qemu_irq irq;
qemu_irq smi_irq;
int smm_enabled;
bool smm_compat;
Notifier machine_ready;
Notifier powerdown_notifier;

Expand Down Expand Up @@ -496,7 +497,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)

acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_cnt_init(&s->ar, &s->io, s->disable_s3, s->disable_s4, s->s4_val);
acpi_pm1_cnt_init(&s->ar, &s->io, s->disable_s3, s->disable_s4, s->s4_val,
!s->smm_compat && !s->smm_enabled);
acpi_gpe_init(&s->ar, GPE_LEN);

s->powerdown_notifier.notify = piix4_pm_powerdown_req;
Expand Down Expand Up @@ -642,6 +644,7 @@ static Property piix4_pm_properties[] = {
use_acpi_root_pci_hotplug, true),
DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
acpi_memory_hotplug.is_enabled, true),
DEFINE_PROP_BOOL("smm-compat", PIIX4PMState, smm_compat, false),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down
5 changes: 4 additions & 1 deletion hw/core/machine.c
Expand Up @@ -36,7 +36,10 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-pci.h"

GlobalProperty hw_compat_5_2[] = {};
GlobalProperty hw_compat_5_2[] = {
{ "ICH9-LPC", "smm-compat", "on"},
{ "PIIX4_PM", "smm-compat", "on"},
};
const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2);

GlobalProperty hw_compat_5_1[] = {
Expand Down
72 changes: 66 additions & 6 deletions hw/i386/acpi-build.c
Expand Up @@ -139,6 +139,14 @@ const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio = {
static void init_common_fadt_data(MachineState *ms, Object *o,
AcpiFadtData *data)
{
X86MachineState *x86ms = X86_MACHINE(ms);
/*
* "ICH9-LPC" or "PIIX4_PM" has "smm-compat" property to keep the old
* behavior for compatibility irrelevant to smm_enabled, which doesn't
* comforms to ACPI spec.
*/
bool smm_enabled = object_property_get_bool(o, "smm-compat", NULL) ?
true : x86_machine_is_smm_enabled(x86ms);
uint32_t io = object_property_get_uint(o, ACPI_PM_PROP_PM_IO_BASE, NULL);
AmlAddressSpace as = AML_AS_SYSTEM_IO;
AcpiFadtData fadt = {
Expand All @@ -159,12 +167,16 @@ static void init_common_fadt_data(MachineState *ms, Object *o,
.rtc_century = RTC_CENTURY,
.plvl2_lat = 0xfff /* C2 state not supported */,
.plvl3_lat = 0xfff /* C3 state not supported */,
.smi_cmd = ACPI_PORT_SMI_CMD,
.smi_cmd = smm_enabled ? ACPI_PORT_SMI_CMD : 0,
.sci_int = object_property_get_uint(o, ACPI_PM_PROP_SCI_INT, NULL),
.acpi_enable_cmd =
object_property_get_uint(o, ACPI_PM_PROP_ACPI_ENABLE_CMD, NULL),
smm_enabled ?
object_property_get_uint(o, ACPI_PM_PROP_ACPI_ENABLE_CMD, NULL) :
0,
.acpi_disable_cmd =
object_property_get_uint(o, ACPI_PM_PROP_ACPI_DISABLE_CMD, NULL),
smm_enabled ?
object_property_get_uint(o, ACPI_PM_PROP_ACPI_DISABLE_CMD, NULL) :
0,
.pm1a_evt = { .space_id = as, .bit_width = 4 * 8, .address = io },
.pm1a_cnt = { .space_id = as, .bit_width = 2 * 8,
.address = io + 0x04 },
Expand Down Expand Up @@ -1060,6 +1072,46 @@ static void build_q35_pci0_int(Aml *table)
aml_append(table, sb_scope);
}

static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
{
Aml *dev;
Aml *resource_template;

/* DRAM controller */
dev = aml_device("DRAC");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C01")));

resource_template = aml_resource_template();
if (mcfg->base + mcfg->size - 1 >= (1ULL << 32)) {
aml_append(resource_template,
aml_qword_memory(AML_POS_DECODE,
AML_MIN_FIXED,
AML_MAX_FIXED,
AML_NON_CACHEABLE,
AML_READ_WRITE,
0x0000000000000000,
mcfg->base,
mcfg->base + mcfg->size - 1,
0x0000000000000000,
mcfg->size));
} else {
aml_append(resource_template,
aml_dword_memory(AML_POS_DECODE,
AML_MIN_FIXED,
AML_MAX_FIXED,
AML_NON_CACHEABLE,
AML_READ_WRITE,
0x0000000000000000,
mcfg->base,
mcfg->base + mcfg->size - 1,
0x0000000000000000,
mcfg->size));
}
aml_append(dev, aml_name_decl("_CRS", resource_template));

return dev;
}

static void build_q35_isa_bridge(Aml *table)
{
Aml *dev;
Expand Down Expand Up @@ -1206,6 +1258,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
X86MachineState *x86ms = X86_MACHINE(machine);
AcpiMcfgInfo mcfg;
bool mcfg_valid = !!acpi_get_mcfg(&mcfg);
uint32_t nr_mem = machine->ram_slots;
int root_bus_limit = 0xFF;
PCIBus *bus = NULL;
Expand All @@ -1228,7 +1281,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(sb_scope, dev);
aml_append(dsdt, sb_scope);

build_hpet_aml(dsdt);
if (misc->has_hpet) {
build_hpet_aml(dsdt);
}
build_piix4_isa_bridge(dsdt);
build_isa_devices_aml(dsdt);
if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
Expand All @@ -1244,6 +1299,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
aml_append(dev, build_q35_osc_method());
aml_append(sb_scope, dev);
if (mcfg_valid) {
aml_append(sb_scope, build_q35_dram_controller(&mcfg));
}

if (pm->smi_on_cpuhp) {
/* reserve SMI block resources, IO ports 0xB2, 0xB3 */
Expand Down Expand Up @@ -1272,7 +1330,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,

aml_append(dsdt, sb_scope);

build_hpet_aml(dsdt);
if (misc->has_hpet) {
build_hpet_aml(dsdt);
}
build_q35_isa_bridge(dsdt);
build_isa_devices_aml(dsdt);
build_q35_pci0_int(dsdt);
Expand Down Expand Up @@ -1374,7 +1434,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
* the PCI0._CRS. Add mmconfig to the set so it will be excluded
* too.
*/
if (acpi_get_mcfg(&mcfg)) {
if (mcfg_valid) {
crs_range_insert(crs_range_set.mem_ranges,
mcfg.base, mcfg.base + mcfg.size - 1);
}
Expand Down
1 change: 1 addition & 0 deletions hw/isa/lpc_ich9.c
Expand Up @@ -775,6 +775,7 @@ static const VMStateDescription vmstate_ich9_lpc = {

static Property ich9_lpc_properties[] = {
DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true),
DEFINE_PROP_BOOL("smm-compat", ICH9LPCState, pm.smm_compat, false),
DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
ICH9_LPC_SMI_F_BROADCAST_BIT, true),
DEFINE_PROP_BIT64("x-smi-cpu-hotplug", ICH9LPCState, smi_host_features,
Expand Down
2 changes: 1 addition & 1 deletion hw/isa/vt82c686.c
Expand Up @@ -190,7 +190,7 @@ static void via_pm_realize(PCIDevice *dev, Error **errp)

acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2);
acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2, false);
}

typedef struct via_pm_init_info {
Expand Down
18 changes: 9 additions & 9 deletions hw/net/virtio-net.c
Expand Up @@ -855,19 +855,19 @@ static void failover_add_primary(VirtIONet *n, Error **errp)

id = failover_find_primary_device_id(n);
if (!id) {
error_setg(errp, "Primary device not found");
error_append_hint(errp, "Virtio-net failover will not work. Make "
"sure primary device has parameter"
" failover_pair_id=%s\n", n->netclient_name);
return;
}
opts = qemu_opts_find(qemu_find_opts("device"), id);
if (opts) {
dev = qdev_device_add(opts, &err);
if (err) {
qemu_opts_del(opts);
}
g_assert(opts); /* cannot be NULL because id was found using opts list */
dev = qdev_device_add(opts, &err);
if (err) {
qemu_opts_del(opts);
} else {
error_setg(errp, "Primary device not found");
error_append_hint(errp, "Virtio-net failover will not work. Make "
"sure primary device has parameter"
" failover_pair_id=<virtio-net-id>\n");
object_unref(OBJECT(dev));
}
error_propagate(errp, err);
}
Expand Down
1 change: 1 addition & 0 deletions hw/pci-host/gpex-acpi.c
Expand Up @@ -175,6 +175,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));
aml_append(dev, aml_name_decl("_STR", aml_unicode("pxb Device")));
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
if (numa_node != NUMA_NODE_UNASSIGNED) {
aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
}
Expand Down
6 changes: 2 additions & 4 deletions hw/pci/pci.c
Expand Up @@ -2127,10 +2127,8 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
if (!(pci_dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)
&& (PCI_FUNC(pci_dev->devfn) == 0)) {
qdev->allow_unplug_during_migration = true;
} else {
if ((pci_dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)
|| (PCI_FUNC(pci_dev->devfn) != 0)) {
error_setg(errp, "failover: primary device must be in its own "
"PCI slot");
pci_qdev_unrealize(DEVICE(pci_dev));
Expand Down
19 changes: 9 additions & 10 deletions hw/pci/pcie.c
Expand Up @@ -75,11 +75,6 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version)
QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1) |
QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT));

if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}

/* We changed link status bits over time, and changing them across
* migrations is generally fine as hardware changes them too.
* Let's not bother checking.
Expand Down Expand Up @@ -125,8 +120,7 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev)
*/
pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP,
PCI_EXP_LNKCAP_DLLLARC);
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
/* the PCI_EXP_LNKSTA_DLLLA will be set in the hotplug function */

/*
* Target Link Speed defaults to the highest link speed supported by
Expand Down Expand Up @@ -427,14 +421,16 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
PCIDevice *pci_dev = PCI_DEVICE(dev);
uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);

/* Don't send event when device is enabled during qemu machine creation:
* it is present on boot, no hotplug event is necessary. We do send an
* event when the device is disabled later. */
if (!dev->hotplugged) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
(lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
Expand All @@ -448,7 +444,8 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
if (pci_get_function_0(pci_dev)) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
if (pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
(lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
Expand Down Expand Up @@ -640,6 +637,7 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
uint32_t pos = dev->exp.exp_cap;
uint8_t *exp_cap = dev->config + pos;
uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);

if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
/*
Expand Down Expand Up @@ -695,7 +693,8 @@ void pcie_cap_slot_write_config(PCIDevice *dev,

pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) {
if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
(lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
Expand Down
4 changes: 3 additions & 1 deletion include/hw/acpi/acpi.h
Expand Up @@ -128,6 +128,7 @@ struct ACPIPM1CNT {
MemoryRegion io;
uint16_t cnt;
uint8_t s4_val;
bool acpi_only;
};

struct ACPIGPE {
Expand Down Expand Up @@ -163,7 +164,8 @@ void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,

/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
bool disable_s3, bool disable_s4, uint8_t s4_val);
bool disable_s3, bool disable_s4, uint8_t s4_val,
bool acpi_only);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
Expand Down
1 change: 1 addition & 0 deletions include/hw/acpi/ich9.h
Expand Up @@ -59,6 +59,7 @@ typedef struct ICH9LPCPMRegs {
uint8_t disable_s4;
uint8_t s4_val;
uint8_t smm_enabled;
bool smm_compat;
bool enable_tco;
TCOIORegs tco_regs;
} ICH9LPCPMRegs;
Expand Down
4 changes: 3 additions & 1 deletion scripts/checkpatch.pl
Expand Up @@ -1530,7 +1530,9 @@ sub process {
($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
$line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
(defined($1) || defined($2))))) {
(defined($1) || defined($2)))) &&
!(($realfile ne '') &&
($realfile eq $acpi_testexpected))) {
$reported_maintainer_file = 1;
WARN("added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
}
Expand Down
Binary file added tests/data/acpi/pc/DSDT.nohpet
Binary file not shown.
Binary file added tests/data/acpi/pc/FACP.nosmm
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.acpihmat
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.bridge
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.cphp
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.dimmpxm
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.ipmibt
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.memhp
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.mmio64
Binary file not shown.
Binary file added tests/data/acpi/q35/DSDT.nohpet
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.numamem
Binary file not shown.
Binary file modified tests/data/acpi/q35/DSDT.tis
Binary file not shown.
Binary file added tests/data/acpi/q35/FACP.nosmm
Binary file not shown.
Binary file modified tests/data/acpi/virt/DSDT.pxb
Binary file not shown.

0 comments on commit 51db2d7

Please sign in to comment.