Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

pc, acpi, pci, virtio: fixes, cleanups, features, tests

Some fixes and cleanups. New tests.
Configurable tx queue size for virtio-net.

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

# gpg: Signature made Mon 03 Jul 2017 20:43:17 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# 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: (21 commits)
  i386/acpi: update expected acpi files
  virtio-net: fix tx queue size for !vhost-user
  tests: Add unit tests for the VM Generation ID feature
  vhost-user: unregister slave req handler at cleanup time
  vhost: ensure vhost_ops are set before calling iotlb callback
  intel_iommu: fix migration breakage on mr switch
  hw/acpi: remove dead acpi code
  fw_cfg: move setting of FW_CFG_VERSION_DMA bit to fw_cfg_init1()
  fw_cfg: don't map the fw_cfg IO ports in fw_cfg_io_realize()
  i386/kvm/pci-assign: Use errp directly rather than local_err
  i386/kvm/pci-assign: Fix return type of verify_irqchip_kernel()
  pci: Convert shpc_init() to Error
  pci: Convert to realize
  pci: Replace pci_add_capability2() with pci_add_capability()
  pci: Make errp the last parameter of pci_add_capability()
  pci: Fix the wrong assertion.
  pci: Add comment for pci_add_capability2()
  pci: Clean up error checking in pci_add_capability()
  intel_iommu: relax iq tail check on VTD_GCMD_QIE enable
  hw/pci-bridge/dec: Classify the DEC PCI bridge as bridge device
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2017-07-04 11:17:02 +01:00
41 changed files with 493 additions and 205 deletions
-10
View File
@@ -1912,16 +1912,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_piix4_pci_hotplug(dsdt);
build_piix4_pci0_int(dsdt);
} else {
sb_scope = aml_scope("_SB");
aml_append(sb_scope,
aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(0xae00), 0x0c));
aml_append(sb_scope,
aml_operation_region("PCSB", AML_SYSTEM_IO, aml_int(0xae0c), 0x01));
field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
aml_append(field, aml_named_field("PCIB", 8));
aml_append(sb_scope, field);
aml_append(dsdt, sb_scope);
sb_scope = aml_scope("_SB");
dev = aml_device("PCI0");
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
+17 -7
View File
@@ -1158,13 +1158,23 @@ static void amdvi_realize(DeviceState *dev, Error **err)
x86_iommu->type = TYPE_AMD;
qdev_set_parent_bus(DEVICE(&s->pci), &bus->qbus);
object_property_set_bool(OBJECT(&s->pci), true, "realized", err);
s->capab_offset = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
AMDVI_CAPAB_SIZE);
assert(s->capab_offset > 0);
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0, AMDVI_CAPAB_REG_SIZE);
assert(ret > 0);
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0, AMDVI_CAPAB_REG_SIZE);
assert(ret > 0);
ret = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
AMDVI_CAPAB_SIZE, err);
if (ret < 0) {
return;
}
s->capab_offset = ret;
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0,
AMDVI_CAPAB_REG_SIZE, err);
if (ret < 0) {
return;
}
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0,
AMDVI_CAPAB_REG_SIZE, err);
if (ret < 0) {
return;
}
/* set up MMIO */
memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",
+34 -14
View File
@@ -1450,10 +1450,7 @@ static uint64_t vtd_iotlb_flush(IntelIOMMUState *s, uint64_t val)
return iaig;
}
static inline bool vtd_queued_inv_enable_check(IntelIOMMUState *s)
{
return s->iq_tail == 0;
}
static void vtd_fetch_inv_desc(IntelIOMMUState *s);
static inline bool vtd_queued_inv_disable_check(IntelIOMMUState *s)
{
@@ -1468,16 +1465,24 @@ static void vtd_handle_gcmd_qie(IntelIOMMUState *s, bool en)
trace_vtd_inv_qi_enable(en);
if (en) {
if (vtd_queued_inv_enable_check(s)) {
s->iq = iqa_val & VTD_IQA_IQA_MASK;
/* 2^(x+8) entries */
s->iq_size = 1UL << ((iqa_val & VTD_IQA_QS) + 8);
s->qi_enabled = true;
trace_vtd_inv_qi_setup(s->iq, s->iq_size);
/* Ok - report back to driver */
vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_QIES);
} else {
trace_vtd_err_qi_enable(s->iq_tail);
s->iq = iqa_val & VTD_IQA_IQA_MASK;
/* 2^(x+8) entries */
s->iq_size = 1UL << ((iqa_val & VTD_IQA_QS) + 8);
s->qi_enabled = true;
trace_vtd_inv_qi_setup(s->iq, s->iq_size);
/* Ok - report back to driver */
vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_QIES);
if (s->iq_tail != 0) {
/*
* This is a spec violation but Windows guests are known to set up
* Queued Invalidation this way so we allow the write and process
* Invalidation Descriptors right away.
*/
trace_vtd_warn_invalid_qi_tail(s->iq_tail);
if (!(vtd_get_long_raw(s, DMAR_FSTS_REG) & VTD_FSTS_IQE)) {
vtd_fetch_inv_desc(s);
}
}
} else {
if (vtd_queued_inv_disable_check(s)) {
@@ -2332,11 +2337,26 @@ static void vtd_iommu_notify_flag_changed(MemoryRegion *iommu,
}
}
static int vtd_post_load(void *opaque, int version_id)
{
IntelIOMMUState *iommu = opaque;
/*
* Memory regions are dynamically turned on/off depending on
* context entry configurations from the guest. After migration,
* we need to make sure the memory regions are still correct.
*/
vtd_switch_address_space_all(iommu);
return 0;
}
static const VMStateDescription vtd_vmstate = {
.name = "iommu-intel",
.version_id = 1,
.minimum_version_id = 1,
.priority = MIG_PRI_IOMMU,
.post_load = vtd_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT64(root, IntelIOMMUState),
VMSTATE_UINT64(intr_root, IntelIOMMUState),
+20 -34
View File
@@ -824,12 +824,13 @@ static void assign_device(AssignedDevice *dev, Error **errp)
}
}
static void verify_irqchip_in_kernel(Error **errp)
static int verify_irqchip_in_kernel(Error **errp)
{
if (kvm_irqchip_in_kernel()) {
return;
return -1;
}
error_setg(errp, "pci-assign requires KVM with in-kernel irqchip enabled");
return 0;
}
static int assign_intx(AssignedDevice *dev, Error **errp)
@@ -838,7 +839,6 @@ static int assign_intx(AssignedDevice *dev, Error **errp)
PCIINTxRoute intx_route;
bool intx_host_msi;
int r;
Error *local_err = NULL;
/* Interrupt PIN 0 means don't use INTx */
if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) {
@@ -846,9 +846,7 @@ static int assign_intx(AssignedDevice *dev, Error **errp)
return 0;
}
verify_irqchip_in_kernel(&local_err);
if (local_err) {
error_propagate(errp, local_err);
if (verify_irqchip_in_kernel(errp) < 0) {
return -ENOTSUP;
}
@@ -1234,7 +1232,6 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
AssignedDevice *dev = PCI_ASSIGN(pci_dev);
PCIRegion *pci_region = dev->real_device.regions;
int ret, pos;
Error *local_err = NULL;
/* Clear initial capabilities pointer and status copied from hw */
pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0);
@@ -1246,18 +1243,15 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
* MSI capability is the 1st capability in capability config */
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);
if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {
verify_irqchip_in_kernel(&local_err);
if (local_err) {
error_propagate(errp, local_err);
if (verify_irqchip_in_kernel(errp) < 0) {
return -ENOTSUP;
}
dev->dev.cap_present |= QEMU_PCI_CAP_MSI;
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
/* Only 32-bit/no-mask currently supported */
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
pci_dev->msi_cap = pos;
@@ -1281,17 +1275,14 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
uint32_t msix_table_entry;
uint16_t msix_max;
verify_irqchip_in_kernel(&local_err);
if (local_err) {
error_propagate(errp, local_err);
if (verify_irqchip_in_kernel(errp) < 0) {
return -ENOTSUP;
}
dev->dev.cap_present |= QEMU_PCI_CAP_MSIX;
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
pci_dev->msix_cap = pos;
@@ -1318,10 +1309,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
if (pos) {
uint16_t pmc;
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
@@ -1386,10 +1376,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
return -EINVAL;
}
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_EXP, pos, size,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_EXP, pos, size,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
@@ -1462,10 +1451,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
uint32_t status;
/* Only expose the minimum, 8 byte capability */
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PCIX, pos, 8,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_PCIX, pos, 8,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
@@ -1490,10 +1478,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0);
if (pos) {
/* Direct R/W passthrough */
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VPD, pos, 8,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_VPD, pos, 8,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
@@ -1508,10 +1495,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
pos += PCI_CAP_LIST_NEXT) {
uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS);
/* Direct R/W passthrough */
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VNDR, pos, len,
&local_err);
ret = pci_add_capability(pci_dev, PCI_CAP_ID_VNDR, pos, len,
errp);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
}
+1 -1
View File
@@ -74,7 +74,7 @@ vtd_err_dmar_slpte_read_error(uint64_t iova, int level) "iova 0x%"PRIx64" level
vtd_err_dmar_slpte_perm_error(uint64_t iova, int level, uint64_t slpte, bool is_write) "iova 0x%"PRIx64" level %d slpte 0x%"PRIx64" write %d"
vtd_err_dmar_slpte_resv_error(uint64_t iova, int level, uint64_t slpte) "iova 0x%"PRIx64" level %d slpte 0x%"PRIx64
vtd_err_dmar_translate(uint8_t bus, uint8_t slot, uint8_t func, uint64_t iova) "dev %02x:%02x.%02x iova 0x%"PRIx64
vtd_err_qi_enable(uint16_t tail) "tail 0x%"PRIx16
vtd_warn_invalid_qi_tail(uint16_t tail) "tail 0x%"PRIx16
vtd_err_qi_disable(uint16_t head, uint16_t tail, int type) "head 0x%"PRIx16" tail 0x%"PRIx16" last_desc_type %d"
vtd_err_qi_tail(uint16_t tail, uint16_t size) "tail 0x%"PRIx16" size 0x%"PRIx16
vtd_err_irte(int index, uint64_t lo, uint64_t hi) "index %d low 0x%"PRIx64" high 0x%"PRIx64
+1 -1
View File
@@ -130,7 +130,7 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
&d->ahci.mem);
sata_cap_offset = pci_add_capability2(dev, PCI_CAP_ID_SATA,
sata_cap_offset = pci_add_capability(dev, PCI_CAP_ID_SATA,
ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE,
errp);
if (sata_cap_offset < 0) {
+19 -13
View File
@@ -47,6 +47,7 @@
#include "e1000e_core.h"
#include "trace.h"
#include "qapi/error.h"
#define TYPE_E1000E "e1000e"
#define E1000E(obj) OBJECT_CHECK(E1000EState, (obj), TYPE_E1000E)
@@ -372,22 +373,27 @@ e1000e_gen_dsn(uint8_t *mac)
static int
e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc)
{
int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset, PCI_PM_SIZEOF);
Error *local_err = NULL;
int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset,
PCI_PM_SIZEOF, &local_err);
if (ret >= 0) {
pci_set_word(pdev->config + offset + PCI_PM_PMC,
PCI_PM_CAP_VER_1_1 |
pmc);
pci_set_word(pdev->wmask + offset + PCI_PM_CTRL,
PCI_PM_CTRL_STATE_MASK |
PCI_PM_CTRL_PME_ENABLE |
PCI_PM_CTRL_DATA_SEL_MASK);
pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL,
PCI_PM_CTRL_PME_STATUS);
if (local_err) {
error_report_err(local_err);
return ret;
}
pci_set_word(pdev->config + offset + PCI_PM_PMC,
PCI_PM_CAP_VER_1_1 |
pmc);
pci_set_word(pdev->wmask + offset + PCI_PM_CTRL,
PCI_PM_CTRL_STATE_MASK |
PCI_PM_CTRL_PME_ENABLE |
PCI_PM_CTRL_DATA_SEL_MASK);
pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL,
PCI_PM_CTRL_PME_STATUS);
return ret;
}
+14 -4
View File
@@ -48,6 +48,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/dma.h"
#include "qemu/bitops.h"
#include "qapi/error.h"
/* QEMU sends frames smaller than 60 bytes to ethernet nics.
* Such frames are rejected by real nics and their emulations.
@@ -494,7 +495,7 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
}
#endif
static void e100_pci_reset(EEPRO100State * s)
static void e100_pci_reset(EEPRO100State *s, Error **errp)
{
E100PCIDeviceInfo *info = eepro100_get_class(s);
uint32_t device = s->device;
@@ -570,8 +571,12 @@ static void e100_pci_reset(EEPRO100State * s)
/* Power Management Capabilities */
int cfg_offset = 0xdc;
int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,
cfg_offset, PCI_PM_SIZEOF);
assert(r >= 0);
cfg_offset, PCI_PM_SIZEOF,
errp);
if (r < 0) {
return;
}
pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);
#if 0 /* TODO: replace dummy code for power management emulation. */
/* TODO: Power Management Control / Status. */
@@ -1858,12 +1863,17 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
{
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
E100PCIDeviceInfo *info = eepro100_get_class(s);
Error *local_err = NULL;
TRACE(OTHER, logout("\n"));
s->device = info->device;
e100_pci_reset(s);
e100_pci_reset(s, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
/* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
* i82559 and later support 64 or 256 word EEPROM. */
+42 -2
View File
@@ -34,8 +34,11 @@
/* previously fixed value */
#define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256
#define VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE 256
/* for now, only allow larger queues; with virtio-1, guest can downsize */
#define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
#define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
/*
* Calculate the number of bytes up to and including the given 'field' of
@@ -495,6 +498,24 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
}
}
static int virtio_net_max_tx_queue_size(VirtIONet *n)
{
NetClientState *peer = n->nic_conf.peers.ncs[0];
/*
* Backends other than vhost-user don't support max queue size.
*/
if (!peer) {
return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE;
}
if (peer->info->type != NET_CLIENT_DRIVER_VHOST_USER) {
return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE;
}
return VIRTQUEUE_MAX_SIZE;
}
static int peer_attach(VirtIONet *n, int index)
{
NetClientState *nc = qemu_get_subqueue(n->nic, index);
@@ -1508,15 +1529,18 @@ static void virtio_net_add_queue(VirtIONet *n, int index)
n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size,
virtio_net_handle_rx);
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
n->vqs[index].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
virtio_add_queue(vdev, n->net_conf.tx_queue_size,
virtio_net_handle_tx_timer);
n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[index]);
} else {
n->vqs[index].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
virtio_add_queue(vdev, n->net_conf.tx_queue_size,
virtio_net_handle_tx_bh);
n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]);
}
@@ -1927,6 +1951,17 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
return;
}
if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE ||
n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE ||
!is_power_of_2(n->net_conf.tx_queue_size)) {
error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), "
"must be a power of 2 between %d and %d",
n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE,
VIRTQUEUE_MAX_SIZE);
virtio_cleanup(vdev);
return;
}
n->max_queues = MAX(n->nic_conf.peers.queues, 1);
if (n->max_queues * 2 + 1 > VIRTIO_QUEUE_MAX) {
error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
@@ -1947,6 +1982,9 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
error_report("Defaulting to \"bh\"");
}
n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n),
n->net_conf.tx_queue_size);
for (i = 0; i < n->max_queues; i++) {
virtio_net_add_queue(n, i);
}
@@ -2106,6 +2144,8 @@ static Property virtio_net_properties[] = {
DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx),
DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size,
VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE),
DEFINE_PROP_UINT16("tx_queue_size", VirtIONet, net_conf.tx_queue_size,
VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE),
DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
true),
+15 -17
View File
@@ -96,7 +96,6 @@ struct FWCfgIoState {
/*< public >*/
MemoryRegion comb_iomem;
uint32_t iobase, dma_iobase;
};
struct FWCfgMemState {
@@ -914,6 +913,7 @@ static void fw_cfg_init1(DeviceState *dev)
{
FWCfgState *s = FW_CFG(dev);
MachineState *machine = MACHINE(qdev_get_machine());
uint32_t version = FW_CFG_VERSION;
assert(!object_resolve_path(FW_CFG_PATH, NULL));
@@ -928,6 +928,12 @@ static void fw_cfg_init1(DeviceState *dev)
fw_cfg_bootsplash(s);
fw_cfg_reboot(s);
if (s->dma_enabled) {
version |= FW_CFG_VERSION_DMA;
}
fw_cfg_add_i32(s, FW_CFG_ID, version);
s->machine_ready.notify = fw_cfg_machine_ready;
qemu_add_machine_init_done_notifier(&s->machine_ready);
}
@@ -936,30 +942,31 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
AddressSpace *dma_as)
{
DeviceState *dev;
SysBusDevice *sbd;
FWCfgIoState *ios;
FWCfgState *s;
uint32_t version = FW_CFG_VERSION;
bool dma_requested = dma_iobase && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
qdev_prop_set_uint32(dev, "iobase", iobase);
qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase);
if (!dma_requested) {
qdev_prop_set_bit(dev, "dma_enabled", false);
}
fw_cfg_init1(dev);
sbd = SYS_BUS_DEVICE(dev);
ios = FW_CFG_IO(dev);
sysbus_add_io(sbd, iobase, &ios->comb_iomem);
s = FW_CFG(dev);
if (s->dma_enabled) {
/* 64 bits for the address field */
s->dma_as = dma_as;
s->dma_addr = 0;
version |= FW_CFG_VERSION_DMA;
sysbus_add_io(sbd, dma_iobase, &s->dma_iomem);
}
fw_cfg_add_i32(s, FW_CFG_ID, version);
return s;
}
@@ -975,7 +982,6 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
DeviceState *dev;
SysBusDevice *sbd;
FWCfgState *s;
uint32_t version = FW_CFG_VERSION;
bool dma_requested = dma_addr && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
@@ -996,11 +1002,8 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
s->dma_as = dma_as;
s->dma_addr = 0;
sysbus_mmio_map(sbd, 2, dma_addr);
version |= FW_CFG_VERSION_DMA;
}
fw_cfg_add_i32(s, FW_CFG_ID, version);
return s;
}
@@ -1059,8 +1062,6 @@ static void fw_cfg_file_slots_allocate(FWCfgState *s, Error **errp)
}
static Property fw_cfg_io_properties[] = {
DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1),
DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
true),
DEFINE_PROP_UINT16("x-file-slots", FWCfgIoState, parent_obj.file_slots,
@@ -1071,7 +1072,6 @@ static Property fw_cfg_io_properties[] = {
static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
{
FWCfgIoState *s = FW_CFG_IO(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Error *local_err = NULL;
fw_cfg_file_slots_allocate(FW_CFG(s), &local_err);
@@ -1085,13 +1085,11 @@ static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
* of the i/o region used is FW_CFG_CTL_SIZE */
memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops,
FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
sysbus_add_io(sbd, s->iobase, &s->comb_iomem);
if (FW_CFG(s)->dma_enabled) {
memory_region_init_io(&FW_CFG(s)->dma_iomem, OBJECT(s),
&fw_cfg_dma_mem_ops, FW_CFG(s), "fwcfg.dma",
sizeof(dma_addr_t));
sysbus_add_io(sbd, s->dma_iobase, &FW_CFG(s)->dma_iomem);
}
}
+2
View File
@@ -62,6 +62,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
k->realize = dec_pci_bridge_realize;
k->exit = pci_bridge_exitfn;
k->vendor_id = PCI_VENDOR_ID_DEC;
@@ -118,6 +119,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
k->realize = dec_21154_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_DEC;
k->device_id = PCI_DEVICE_ID_DEC_21154;
+6 -6
View File
@@ -44,6 +44,7 @@
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/i386/ich9.h"
#include "qapi/error.h"
/*****************************************************************************/
@@ -58,24 +59,23 @@ typedef struct I82801b11Bridge {
/*< public >*/
} I82801b11Bridge;
static int i82801b11_bridge_initfn(PCIDevice *d)
static void i82801b11_bridge_realize(PCIDevice *d, Error **errp)
{
int rc;
pci_bridge_initfn(d, TYPE_PCI_BUS);
rc = pci_bridge_ssvid_init(d, I82801ba_SSVID_OFFSET,
I82801ba_SSVID_SVID, I82801ba_SSVID_SSID);
I82801ba_SSVID_SVID, I82801ba_SSVID_SSID,
errp);
if (rc < 0) {
goto err_bridge;
}
pci_config_set_prog_interface(d->config, PCI_CLASS_BRIDGE_PCI_INF_SUB);
return 0;
return;
err_bridge:
pci_bridge_exitfn(d);
return rc;
}
static const VMStateDescription i82801b11_bridge_dev_vmstate = {
@@ -95,7 +95,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
k->revision = ICH9_D2P_A2_REVISION;
k->init = i82801b11_bridge_initfn;
k->realize = i82801b11_bridge_realize;
k->config_write = pci_bridge_write_config;
dc->vmsd = &i82801b11_bridge_dev_vmstate;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+6 -8
View File
@@ -49,7 +49,7 @@ struct PCIBridgeDev {
};
typedef struct PCIBridgeDev PCIBridgeDev;
static int pci_bridge_dev_initfn(PCIDevice *dev)
static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp)
{
PCIBridge *br = PCI_BRIDGE(dev);
PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
@@ -62,7 +62,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
dev->config[PCI_INTERRUPT_PIN] = 0x1;
memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar",
shpc_bar_size(dev));
err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0);
err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0, errp);
if (err) {
goto shpc_error;
}
@@ -71,7 +71,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
bridge_dev->msi = ON_OFF_AUTO_OFF;
}
err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0);
err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0, errp);
if (err) {
goto slotid_error;
}
@@ -87,7 +87,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
/* Can't satisfy user's explicit msi=on request, fail */
error_append_hint(&local_err, "You have to use msi=auto (default) "
"or msi=off with this machine type.\n");
error_report_err(local_err);
error_propagate(errp, local_err);
goto msi_error;
}
assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
@@ -101,7 +101,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
}
return 0;
return;
msi_error:
slotid_cap_cleanup(dev);
@@ -111,8 +111,6 @@ slotid_error:
}
shpc_error:
pci_bridge_exitfn(dev);
return err;
}
static void pci_bridge_dev_exitfn(PCIDevice *dev)
@@ -216,7 +214,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->init = pci_bridge_dev_initfn;
k->realize = pci_bridge_dev_realize;
k->exit = pci_bridge_dev_exitfn;
k->config_write = pci_bridge_dev_write_config;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
+9 -9
View File
@@ -59,29 +59,30 @@ static void rp_realize(PCIDevice *d, Error **errp)
PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d);
PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
int rc;
Error *local_err = NULL;
pci_config_set_interrupt_pin(d->config, 1);
pci_bridge_initfn(d, TYPE_PCIE_BUS);
pcie_port_init_reg(d);
rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, rpc->ssid);
rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id,
rpc->ssid, errp);
if (rc < 0) {
error_setg(errp, "Can't init SSV ID, error %d", rc);
error_append_hint(errp, "Can't init SSV ID, error %d\n", rc);
goto err_bridge;
}
if (rpc->interrupts_init) {
rc = rpc->interrupts_init(d, &local_err);
rc = rpc->interrupts_init(d, errp);
if (rc < 0) {
error_propagate(errp, local_err);
goto err_bridge;
}
}
rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, p->port);
rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT,
p->port, errp);
if (rc < 0) {
error_setg(errp, "Can't add Root Port capability, error %d", rc);
error_append_hint(errp, "Can't add Root Port capability, "
"error %d\n", rc);
goto err_int;
}
@@ -98,9 +99,8 @@ static void rp_realize(PCIDevice *d, Error **errp)
}
rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset,
PCI_ERR_SIZEOF, &local_err);
PCI_ERR_SIZEOF, errp);
if (rc < 0) {
error_propagate(errp, local_err);
goto err;
}
pcie_aer_root_init(d);
+9 -11
View File
@@ -56,33 +56,33 @@ static void xio3130_downstream_reset(DeviceState *qdev)
pci_bridge_reset(qdev);
}
static int xio3130_downstream_initfn(PCIDevice *d)
static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
{
PCIEPort *p = PCIE_PORT(d);
PCIESlot *s = PCIE_SLOT(d);
int rc;
Error *err = NULL;
pci_bridge_initfn(d, TYPE_PCIE_BUS);
pcie_port_init_reg(d);
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err);
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
errp);
if (rc < 0) {
assert(rc == -ENOTSUP);
error_report_err(err);
goto err_bridge;
}
rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
XIO3130_SSVID_SVID, XIO3130_SSVID_SSID);
XIO3130_SSVID_SVID, XIO3130_SSVID_SSID,
errp);
if (rc < 0) {
goto err_bridge;
}
rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,
p->port);
p->port, errp);
if (rc < 0) {
goto err_msi;
}
@@ -98,13 +98,12 @@ static int xio3130_downstream_initfn(PCIDevice *d)
}
rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET,
PCI_ERR_SIZEOF, &err);
PCI_ERR_SIZEOF, errp);
if (rc < 0) {
error_report_err(err);
goto err;
}
return 0;
return;
err:
pcie_chassis_del_slot(s);
@@ -114,7 +113,6 @@ err_msi:
msi_uninit(d);
err_bridge:
pci_bridge_exitfn(d);
return rc;
}
static void xio3130_downstream_exitfn(PCIDevice *d)
@@ -181,7 +179,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
k->is_express = 1;
k->is_bridge = 1;
k->config_write = xio3130_downstream_write_config;
k->init = xio3130_downstream_initfn;
k->realize = xio3130_downstream_realize;
k->exit = xio3130_downstream_exitfn;
k->vendor_id = PCI_VENDOR_ID_TI;
k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
+9 -11
View File
@@ -53,32 +53,32 @@ static void xio3130_upstream_reset(DeviceState *qdev)
pcie_cap_deverr_reset(d);
}
static int xio3130_upstream_initfn(PCIDevice *d)
static void xio3130_upstream_realize(PCIDevice *d, Error **errp)
{
PCIEPort *p = PCIE_PORT(d);
int rc;
Error *err = NULL;
pci_bridge_initfn(d, TYPE_PCIE_BUS);
pcie_port_init_reg(d);
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err);
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
errp);
if (rc < 0) {
assert(rc == -ENOTSUP);
error_report_err(err);
goto err_bridge;
}
rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
XIO3130_SSVID_SVID, XIO3130_SSVID_SSID);
XIO3130_SSVID_SVID, XIO3130_SSVID_SSID,
errp);
if (rc < 0) {
goto err_bridge;
}
rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_UPSTREAM,
p->port);
p->port, errp);
if (rc < 0) {
goto err_msi;
}
@@ -86,13 +86,12 @@ static int xio3130_upstream_initfn(PCIDevice *d)
pcie_cap_deverr_init(d);
rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET,
PCI_ERR_SIZEOF, &err);
PCI_ERR_SIZEOF, errp);
if (rc < 0) {
error_report_err(err);
goto err;
}
return 0;
return;
err:
pcie_cap_exit(d);
@@ -100,7 +99,6 @@ err_msi:
msi_uninit(d);
err_bridge:
pci_bridge_exitfn(d);
return rc;
}
static void xio3130_upstream_exitfn(PCIDevice *d)
@@ -153,7 +151,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
k->is_express = 1;
k->is_bridge = 1;
k->config_write = xio3130_upstream_write_config;
k->init = xio3130_upstream_initfn;
k->realize = xio3130_upstream_realize;
k->exit = xio3130_upstream_exitfn;
k->vendor_id = PCI_VENDOR_ID_TI;
k->device_id = PCI_DEVICE_ID_TI_XIO3130U;
+1 -1
View File
@@ -216,7 +216,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
}
cap_size = msi_cap_sizeof(flags);
config_offset = pci_add_capability2(dev, PCI_CAP_ID_MSI, offset,
config_offset = pci_add_capability(dev, PCI_CAP_ID_MSI, offset,
cap_size, errp);
if (config_offset < 0) {
return config_offset;
+1 -1
View File
@@ -301,7 +301,7 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
return -EINVAL;
}
cap = pci_add_capability2(dev, PCI_CAP_ID_MSIX,
cap = pci_add_capability(dev, PCI_CAP_ID_MSIX,
cap_pos, MSIX_CAP_LENGTH, errp);
if (cap < 0) {
return cap;
+4 -20
View File
@@ -2259,28 +2259,12 @@ static void pci_del_option_rom(PCIDevice *pdev)
}
/*
* if offset = 0,
* Find and reserve space and add capability to the linked list
* in pci config space
* On success, pci_add_capability() returns a positive value
* that the offset of the pci capability.
* On failure, it sets an error and returns a negative error
* code.
*/
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size)
{
int ret;
Error *local_err = NULL;
ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err);
if (local_err) {
assert(ret < 0);
error_report_err(local_err);
} else {
/* success implies a positive offset in config space */
assert(ret > 0);
}
return ret;
}
int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size,
Error **errp)
{
+6 -2
View File
@@ -33,6 +33,7 @@
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "qemu/range.h"
#include "qapi/error.h"
/* PCI bridge subsystem vendor ID helper functions */
#define PCI_SSVID_SIZEOF 8
@@ -40,10 +41,13 @@
#define PCI_SSVID_SSID 6
int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
uint16_t svid, uint16_t ssid)
uint16_t svid, uint16_t ssid,
Error **errp)
{
int pos;
pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset, PCI_SSVID_SIZEOF);
pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset,
PCI_SSVID_SIZEOF, errp);
if (pos < 0) {
return pos;
}

Some files were not shown because too many files have changed in this diff Show More