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, pci, virtio: features, fixes, cleanups

A bunch of fixes, cleanus and new features all over the place.

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

# gpg: Signature made Thu 11 Jan 2018 20:04:57 GMT
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# 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: (23 commits)
  smbus: do not immediately complete commands
  dump-guest-memory.py: fix "You can't do that without a process to debug"
  virtio-pci: Don't force Subsystem Vendor ID = Vendor ID
  intel_iommu: fix error param in string
  intel_iommu: remove X86_IOMMU_PCI_DEVFN_MAX
  vhost-user: document memory accesses
  vhost-user: fix indentation in protocol specification
  hw/pci-host/xilinx: QOM'ify the AXI-PCIe host bridge
  hw/pci-host/piix: QOM'ify the IGD Passthrough host bridge
  tests/pxe-test: Add some extra tests
  tests/pxe-test: Test net booting over IPv6 in some cases
  tests/pxe-test: Use table of testcases rather than open-coding
  tests/pxe-test: Remove unnecessary special case test functions
  virtio_error: don't invoke status callbacks
  pci: Eliminate pci_find_primary_bus()
  pci: Eliminate redundant PCIDevice::bus pointer
  pci: Add pci_dev_bus_num() helper
  pci: Move bridge data structures from pci_bus.h to pci_bridge.h
  pci: Rename root bus initialization functions for clarity
  tests: add test to check VirtQueue object
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jan 12, 2018
2 parents 997eba2 + acc95bc commit 36b5e43
Show file tree
Hide file tree
Showing 53 changed files with 642 additions and 386 deletions.
37 changes: 32 additions & 5 deletions docs/interop/vhost-user.txt
Expand Up @@ -53,8 +53,8 @@ Depending on the request type, payload can be:

* A vring state description
---------------
| index | num |
---------------
| index | num |
---------------

Index: a 32-bit index
Num: a 32-bit number
Expand All @@ -66,11 +66,14 @@ Depending on the request type, payload can be:

Index: a 32-bit vring index
Flags: a 32-bit vring flags
Descriptor: a 64-bit user address of the vring descriptor table
Used: a 64-bit user address of the vring used ring
Available: a 64-bit user address of the vring available ring
Descriptor: a 64-bit ring address of the vring descriptor table
Used: a 64-bit ring address of the vring used ring
Available: a 64-bit ring address of the vring available ring
Log: a 64-bit guest address for logging

Note that a ring address is an IOVA if VIRTIO_F_IOMMU_PLATFORM has been
negotiated. Otherwise it is a user address.

* Memory regions description
---------------------------------------------------
| num regions | padding | region0 | ... | region7 |
Expand Down Expand Up @@ -273,6 +276,30 @@ Once the source has finished migration, rings will be stopped by
the source. No further update must be done before rings are
restarted.

Memory access
-------------

The master sends a list of vhost memory regions to the slave using the
VHOST_USER_SET_MEM_TABLE message. Each region has two base addresses: a guest
address and a user address.

Messages contain guest addresses and/or user addresses to reference locations
within the shared memory. The mapping of these addresses works as follows.

User addresses map to the vhost memory region containing that user address.

When the VIRTIO_F_IOMMU_PLATFORM feature has not been negotiated:

* Guest addresses map to the vhost memory region containing that guest
address.

When the VIRTIO_F_IOMMU_PLATFORM feature has been negotiated:

* Guest addresses are also called I/O virtual addresses (IOVAs). They are
translated to user addresses via the IOTLB.

* The vhost memory region guest address is not used.

IOMMU support
-------------

Expand Down
4 changes: 2 additions & 2 deletions hw/acpi/pcihp.c
Expand Up @@ -223,7 +223,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
int bsel = acpi_pcihp_get_bsel(pdev->bus);
int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
Expand All @@ -246,7 +246,7 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
int bsel = acpi_pcihp_get_bsel(pdev->bus);
int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
Expand Down
7 changes: 4 additions & 3 deletions hw/acpi/piix4.c
Expand Up @@ -460,9 +460,9 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
(memory_region_present(io_as, 0x2f8) ? 0x90 : 0);

if (s->use_acpi_pci_hotplug) {
pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
pci_for_each_bus(pci_get_bus(d), piix4_update_bus_hotplug, s);
} else {
piix4_update_bus_hotplug(d->bus, s);
piix4_update_bus_hotplug(pci_get_bus(d), s);
}
}

Expand Down Expand Up @@ -535,7 +535,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
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), dev->bus, s);
piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
pci_get_bus(dev), s);

piix4_pm_add_propeties(s);
}
Expand Down
30 changes: 8 additions & 22 deletions hw/acpi/vmgenid.c
Expand Up @@ -162,21 +162,6 @@ static void vmgenid_update_guest(VmGenIdState *vms)
}
}

static void vmgenid_set_guid(Object *obj, const char *value, Error **errp)
{
VmGenIdState *vms = VMGENID(obj);

if (!strcmp(value, "auto")) {
qemu_uuid_generate(&vms->guid);
} else if (qemu_uuid_parse(value, &vms->guid) < 0) {
error_setg(errp, "'%s. %s': Failed to parse GUID string: %s",
object_get_typename(OBJECT(vms)), VMGENID_GUID, value);
return;
}

vmgenid_update_guest(vms);
}

/* After restoring an image, we need to update the guest memory and notify
* it of a potential change to VM Generation ID
*/
Expand Down Expand Up @@ -224,23 +209,24 @@ static void vmgenid_realize(DeviceState *dev, Error **errp)
}

qemu_register_reset(vmgenid_handle_reset, vms);

vmgenid_update_guest(vms);
}

static Property vmgenid_device_properties[] = {
DEFINE_PROP_UUID(VMGENID_GUID, VmGenIdState, guid),
DEFINE_PROP_END_OF_LIST(),
};

static void vmgenid_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);

dc->vmsd = &vmstate_vmgenid;
dc->realize = vmgenid_realize;
dc->props = vmgenid_device_properties;
dc->hotpluggable = false;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);

object_class_property_add_str(klass, VMGENID_GUID, NULL,
vmgenid_set_guid, NULL);
object_class_property_set_description(klass, VMGENID_GUID,
"Set Global Unique Identifier "
"(big-endian) or auto for random value",
NULL);
}

static const TypeInfo vmgenid_device_info = {
Expand Down
8 changes: 4 additions & 4 deletions hw/alpha/typhoon.c
Expand Up @@ -881,10 +881,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);

b = pci_register_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, &s->pchip.reg_io,
0, 64, TYPE_PCI_BUS);
b = pci_register_root_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, &s->pchip.reg_io,
0, 64, TYPE_PCI_BUS);
phb->bus = b;
qdev_init_nofail(dev);

Expand Down
61 changes: 61 additions & 0 deletions hw/core/qdev-properties.c
Expand Up @@ -10,6 +10,7 @@
#include "net/hub.h"
#include "qapi/visitor.h"
#include "chardev/char.h"
#include "qemu/uuid.h"

void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp)
Expand Down Expand Up @@ -883,6 +884,66 @@ const PropertyInfo qdev_prop_pci_host_devaddr = {
.set = set_pci_host_devaddr,
};

/* --- UUID --- */

static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
char buffer[UUID_FMT_LEN + 1];
char *p = buffer;

qemu_uuid_unparse(uuid, buffer);

visit_type_str(v, name, &p, errp);
}

#define UUID_VALUE_AUTO "auto"

static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
Error *local_err = NULL;
char *str;

if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
return;
}

visit_type_str(v, name, &str, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}

if (!strcmp(str, UUID_VALUE_AUTO)) {
qemu_uuid_generate(uuid);
} else if (qemu_uuid_parse(str, uuid) < 0) {
error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
}
g_free(str);
}

static void set_default_uuid_auto(Object *obj, const Property *prop)
{
object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort);
}

const PropertyInfo qdev_prop_uuid = {
.name = "str",
.description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
"\" for random value (default)",
.get = get_uuid,
.set = set_uuid,
.set_default_value = set_default_uuid_auto,
};

/* --- support for array properties --- */

/* Used as an opaque for the object properties we add for each
Expand Down
16 changes: 15 additions & 1 deletion hw/i2c/pm_smbus.c
Expand Up @@ -62,6 +62,9 @@ static void smb_transaction(PMSMBus *s)
I2CBus *bus = s->smbus;
int ret;

assert(s->smb_stat & STS_HOST_BUSY);
s->smb_stat &= ~STS_HOST_BUSY;

SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
/* Transaction isn't exec if STS_DEV_ERR bit set */
if ((s->smb_stat & STS_DEV_ERR) != 0) {
Expand Down Expand Up @@ -134,6 +137,13 @@ static void smb_transaction(PMSMBus *s)

}

static void smb_transaction_start(PMSMBus *s)
{
/* Do not execute immediately the command ; it will be
* executed when guest will read SMB_STAT register */
s->smb_stat |= STS_HOST_BUSY;
}

static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
Expand All @@ -149,7 +159,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
case SMBHSTCNT:
s->smb_ctl = val;
if (val & 0x40)
smb_transaction(s);
smb_transaction_start(s);
break;
case SMBHSTCMD:
s->smb_cmd = val;
Expand Down Expand Up @@ -181,6 +191,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
switch(addr) {
case SMBHSTSTS:
val = s->smb_stat;
if (s->smb_stat & STS_HOST_BUSY) {
/* execute command now */
smb_transaction(s);
}
break;
case SMBHSTCNT:
s->smb_index = 0;
Expand Down
12 changes: 6 additions & 6 deletions hw/i386/intel_iommu.c
Expand Up @@ -186,7 +186,7 @@ static void vtd_reset_context_cache(IntelIOMMUState *s)
g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);

while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (!vtd_as) {
continue;
Expand Down Expand Up @@ -1002,7 +1002,7 @@ static void vtd_switch_address_space_all(IntelIOMMUState *s)

g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
for (i = 0; i < PCI_DEVFN_MAX; i++) {
if (!vtd_bus->dev_as[i]) {
continue;
}
Expand Down Expand Up @@ -1294,7 +1294,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
if (vtd_bus) {
devfn = VTD_SID_TO_DEVFN(source_id);
for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
Expand Down Expand Up @@ -2327,7 +2327,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IntelIOMMUNotifierNode *next_node = NULL;

if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
error_report("We need to set cache_mode=1 for intel-iommu to enable "
error_report("We need to set caching-mode=1 for intel-iommu to enable "
"device assignment with IOMMU protection.");
exit(1);
}
Expand Down Expand Up @@ -2699,7 +2699,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
*new_key = (uintptr_t)bus;
/* No corresponding free() */
vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
X86_IOMMU_PCI_DEVFN_MAX);
PCI_DEVFN_MAX);
vtd_bus->bus = bus;
g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
}
Expand Down Expand Up @@ -2982,7 +2982,7 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
IntelIOMMUState *s = opaque;
VTDAddressSpace *vtd_as;

assert(0 <= devfn && devfn < X86_IOMMU_PCI_DEVFN_MAX);
assert(0 <= devfn && devfn < PCI_DEVFN_MAX);

vtd_as = vtd_find_add_as(s, bus, devfn);
return &vtd_as->as;
Expand Down
8 changes: 2 additions & 6 deletions hw/i386/pc_piix.c
Expand Up @@ -394,19 +394,15 @@ static void pc_xen_hvm_init_pci(MachineState *machine)

static void pc_xen_hvm_init(MachineState *machine)
{
PCIBus *bus;
PCMachineState *pcms = PC_MACHINE(machine);

if (!xen_enabled()) {
error_report("xenfv machine requires the xen accelerator");
exit(1);
}

pc_xen_hvm_init_pci(machine);

bus = pci_find_primary_bus();
if (bus != NULL) {
pci_create_simple(bus, -1, "xen-platform");
}
pci_create_simple(pcms->bus, -1, "xen-platform");
}
#endif

Expand Down
12 changes: 6 additions & 6 deletions hw/i386/xen/xen_platform.c
Expand Up @@ -185,11 +185,11 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
UNPLUG_NVME_DISKS)) {
DPRINTF("unplug disks\n");
pci_unplug_disks(pci_dev->bus, val);
pci_unplug_disks(pci_get_bus(pci_dev), val);
}
if (val & UNPLUG_ALL_NICS) {
DPRINTF("unplug nics\n");
pci_unplug_nics(pci_dev->bus);
pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
}
Expand Down Expand Up @@ -371,17 +371,17 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
* If VMDP was to control both disk and LAN it would use 4.
* If it controlled just disk or just LAN, it would use 8 below.
*/
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
pci_unplug_nics(pci_dev->bus);
pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
case 8:
switch (val) {
case 1:
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
break;
case 2:
pci_unplug_nics(pci_dev->bus);
pci_unplug_nics(pci_get_bus(pci_dev));
break;
default:
log_writeb(s, (uint32_t)val);
Expand Down

0 comments on commit 36b5e43

Please sign in to comment.