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, features

Fixes all over the place.
ACPI index support.

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

# gpg: Signature made Mon 22 Mar 2021 22:58:45 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:
  acpi: Move setters/getters of oem fields to X86MachineState
  acpi: Set proper maximum size for "etc/acpi/rsdp" blob
  acpi: Move maximum size logic into acpi_add_rom_blob()
  microvm: Don't open-code "etc/table-loader"
  acpi: Set proper maximum size for "etc/table-loader" blob
  tests: acpi: update expected blobs
  pci: acpi: add _DSM method to PCI devices
  acpi: add aml_to_decimalstring() and aml_call6() helpers
  pci: acpi: ensure that acpi-index is unique
  pci: introduce acpi-index property for PCI device
  tests: acpi: temporary whitelist DSDT changes
  virtio-pmem: fix virtio_pmem_resp assign problem
  vhost-user: Monitor slave channel in vhost_user_read()
  vhost-user: Introduce nested event loop in vhost_user_read()
  vhost-user: Convert slave channel to QIOChannelSocket
  vhost-user: Factor out duplicated slave_fd teardown code
  vhost-user: Fix double-close on slave_read() error path
  vhost-user: Drop misleading EAGAIN checks in slave_read()
  virtio: Fix virtio_mmio_read()/virtio_mmio_write()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Mar 23, 2021
2 parents 5ca634a + d07b228 commit 9741498
Show file tree
Hide file tree
Showing 35 changed files with 583 additions and 308 deletions.
28 changes: 28 additions & 0 deletions hw/acpi/aml-build.c
Expand Up @@ -634,6 +634,19 @@ Aml *aml_to_buffer(Aml *src, Aml *dst)
return var;
}

/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToDecimalString */
Aml *aml_to_decimalstring(Aml *src, Aml *dst)
{
Aml *var = aml_opcode(0x97 /* ToDecimalStringOp */);
aml_append(var, src);
if (dst) {
aml_append(var, dst);
} else {
build_append_byte(var->buf, 0x00 /* NullNameOp */);
}
return var;
}

/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
Aml *aml_store(Aml *val, Aml *target)
{
Expand Down Expand Up @@ -835,6 +848,21 @@ Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
return var;
}

/* helper to call method with 5 arguments */
Aml *aml_call6(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
Aml *arg5, Aml *arg6)
{
Aml *var = aml_alloc();
build_append_namestring(var->buf, "%s", method);
aml_append(var, arg1);
aml_append(var, arg2);
aml_append(var, arg3);
aml_append(var, arg4);
aml_append(var, arg5);
aml_append(var, arg6);
return var;
}

/*
* ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
* Type 1, Large Item Name 0xC
Expand Down
1 change: 0 additions & 1 deletion hw/acpi/pci.c
Expand Up @@ -59,4 +59,3 @@ void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
"MCFG", table_data->len - mcfg_start, 1, oem_id, oem_table_id);
}

104 changes: 102 additions & 2 deletions hw/acpi/pcihp.c
Expand Up @@ -39,18 +39,34 @@
#include "trace.h"

#define ACPI_PCIHP_ADDR 0xae00
#define ACPI_PCIHP_SIZE 0x0014
#define ACPI_PCIHP_SIZE 0x0018
#define PCI_UP_BASE 0x0000
#define PCI_DOWN_BASE 0x0004
#define PCI_EJ_BASE 0x0008
#define PCI_RMV_BASE 0x000c
#define PCI_SEL_BASE 0x0010
#define PCI_AIDX_BASE 0x0014

typedef struct AcpiPciHpFind {
int bsel;
PCIBus *bus;
} AcpiPciHpFind;

static gint g_cmp_uint32(gconstpointer a, gconstpointer b, gpointer user_data)
{
return a - b;
}

static GSequence *pci_acpi_index_list(void)
{
static GSequence *used_acpi_index_list;

if (!used_acpi_index_list) {
used_acpi_index_list = g_sequence_new(NULL);
}
return used_acpi_index_list;
}

static int acpi_pcihp_get_bsel(PCIBus *bus)
{
Error *local_err = NULL;
Expand Down Expand Up @@ -251,16 +267,48 @@ void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off)
acpi_pcihp_update(s);
}

#define ONBOARD_INDEX_MAX (16 * 1024 - 1)

void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
PCIDevice *pdev = PCI_DEVICE(dev);

/* Only hotplugged devices need the hotplug capability. */
if (dev->hotplugged &&
acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))) < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
return;
}

/*
* capped by systemd (see: udev-builtin-net_id.c)
* as it's the only known user honor it to avoid users
* misconfigure QEMU and then wonder why acpi-index doesn't work
*/
if (pdev->acpi_index > ONBOARD_INDEX_MAX) {
error_setg(errp, "acpi-index should be less or equal to %u",
ONBOARD_INDEX_MAX);
return;
}

/*
* make sure that acpi-index is unique across all present PCI devices
*/
if (pdev->acpi_index) {
GSequence *used_indexes = pci_acpi_index_list();

if (g_sequence_lookup(used_indexes, GINT_TO_POINTER(pdev->acpi_index),
g_cmp_uint32, NULL)) {
error_setg(errp, "a PCI device with acpi-index = %" PRIu32
" already exist", pdev->acpi_index);
return;
}
g_sequence_insert_sorted(used_indexes,
GINT_TO_POINTER(pdev->acpi_index),
g_cmp_uint32, NULL);
}
}

void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
Expand Down Expand Up @@ -299,8 +347,22 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
DeviceState *dev, Error **errp)
{
PCIDevice *pdev = PCI_DEVICE(dev);

trace_acpi_pci_unplug(PCI_SLOT(PCI_DEVICE(dev)->devfn),
acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))));

/*
* clean up acpi-index so it could reused by another device
*/
if (pdev->acpi_index) {
GSequence *used_indexes = pci_acpi_index_list();

g_sequence_remove(g_sequence_lookup(used_indexes,
GINT_TO_POINTER(pdev->acpi_index),
g_cmp_uint32, NULL));
}

qdev_unrealize(dev);
}

Expand Down Expand Up @@ -347,7 +409,6 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
trace_acpi_pci_down_read(val);
break;
case PCI_EJ_BASE:
/* No feature defined yet */
trace_acpi_pci_features_read(val);
break;
case PCI_RMV_BASE:
Expand All @@ -357,6 +418,12 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
case PCI_SEL_BASE:
val = s->hotplug_select;
trace_acpi_pci_sel_read(val);
break;
case PCI_AIDX_BASE:
val = s->acpi_index;
s->acpi_index = 0;
trace_acpi_pci_acpi_index_read(val);
break;
default:
break;
}
Expand All @@ -367,8 +434,35 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
static void pci_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
int slot;
PCIBus *bus;
BusChild *kid, *next;
AcpiPciHpState *s = opaque;

s->acpi_index = 0;
switch (addr) {
case PCI_AIDX_BASE:
/*
* fetch acpi-index for specified slot so that follow up read from
* PCI_AIDX_BASE can return it to guest
*/
slot = ctz32(data);

if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
break;
}

bus = acpi_pcihp_find_hotplug_bus(s, s->hotplug_select);
QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
Object *o = OBJECT(kid->child);
PCIDevice *dev = PCI_DEVICE(o);
if (PCI_SLOT(dev->devfn) == slot) {
s->acpi_index = object_property_get_uint(o, "acpi-index", NULL);
break;
}
}
trace_acpi_pci_acpi_index_write(s->hotplug_select, slot, s->acpi_index);
break;
case PCI_EJ_BASE:
if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
break;
Expand Down Expand Up @@ -413,6 +507,12 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
OBJ_PROP_FLAG_READ);
}

bool vmstate_acpi_pcihp_use_acpi_index(void *opaque, int version_id)
{
AcpiPciHpState *s = opaque;
return s->acpi_index;
}

const VMStateDescription vmstate_acpi_pcihp_pci_status = {
.name = "acpi_pcihp_pci_status",
.version_id = 1,
Expand Down
3 changes: 2 additions & 1 deletion hw/acpi/piix4.c
Expand Up @@ -297,7 +297,8 @@ static const VMStateDescription vmstate_acpi = {
2, vmstate_pci_status,
struct AcpiPciHpPciStatus),
VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
vmstate_test_use_acpi_hotplug_bridge),
vmstate_test_use_acpi_hotplug_bridge,
vmstate_acpi_pcihp_use_acpi_index),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
Expand Down
2 changes: 2 additions & 0 deletions hw/acpi/trace-events
Expand Up @@ -41,6 +41,8 @@ acpi_pci_unplug_request(int bsel, int slot) "bsel: %d slot: %d"
acpi_pci_up_read(uint32_t val) "%" PRIu32
acpi_pci_down_read(uint32_t val) "%" PRIu32
acpi_pci_features_read(uint32_t val) "%" PRIu32
acpi_pci_acpi_index_read(uint32_t val) "%" PRIu32
acpi_pci_acpi_index_write(unsigned bsel, unsigned slot, uint32_t aidx) "bsel: %u slot: %u aidx: %" PRIu32
acpi_pci_rmv_read(uint32_t val) "%" PRIu32
acpi_pci_sel_read(uint32_t val) "%" PRIu32
acpi_pci_ej_write(uint64_t addr, uint64_t data) "0x%" PRIx64 " <== %" PRIu64
Expand Down
17 changes: 15 additions & 2 deletions hw/acpi/utils.c
Expand Up @@ -27,9 +27,22 @@
#include "hw/loader.h"

MemoryRegion *acpi_add_rom_blob(FWCfgCallback update, void *opaque,
GArray *blob, const char *name,
uint64_t max_size)
GArray *blob, const char *name)
{
uint64_t max_size;

/* Reserve RAM space for tables: add another order of magnitude. */
if (!strcmp(name, ACPI_BUILD_TABLE_FILE)) {
max_size = 0x200000;
} else if (!strcmp(name, ACPI_BUILD_LOADER_FILE)) {
max_size = 0x10000;
} else if (!strcmp(name, ACPI_BUILD_RSDP_FILE)) {
max_size = 0x1000;
} else {
g_assert_not_reached();
}
g_assert(acpi_data_len(blob) <= max_size);

return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
name, update, opaque, NULL, true);
}
12 changes: 6 additions & 6 deletions hw/arm/virt-acpi-build.c
Expand Up @@ -859,13 +859,13 @@ void virt_acpi_setup(VirtMachineState *vms)
/* Now expose it all to Guest */
build_state->table_mr = acpi_add_rom_blob(virt_acpi_build_update,
build_state, tables.table_data,
ACPI_BUILD_TABLE_FILE,
ACPI_BUILD_TABLE_MAX_SIZE);
ACPI_BUILD_TABLE_FILE);
assert(build_state->table_mr != NULL);

build_state->linker_mr =
acpi_add_rom_blob(virt_acpi_build_update, build_state,
tables.linker->cmd_blob, ACPI_BUILD_LOADER_FILE, 0);
build_state->linker_mr = acpi_add_rom_blob(virt_acpi_build_update,
build_state,
tables.linker->cmd_blob,
ACPI_BUILD_LOADER_FILE);

fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
acpi_data_len(tables.tcpalog));
Expand All @@ -879,7 +879,7 @@ void virt_acpi_setup(VirtMachineState *vms)

build_state->rsdp_mr = acpi_add_rom_blob(virt_acpi_build_update,
build_state, tables.rsdp,
ACPI_BUILD_RSDP_FILE, 0);
ACPI_BUILD_RSDP_FILE);

qemu_register_reset(virt_acpi_build_reset, build_state);
virt_acpi_build_reset(build_state);
Expand Down

0 comments on commit 9741498

Please sign in to comment.