mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 20:19:44 +00:00
pci, virtio, vhost: fixes
A bunch of fixes that missed the release. Most notably we are reverting shpc back to enabled by default state as guests uses that as an indicator that hotplug is supported (even though it's unused). Unfortunately we can't fix this on the stable branch since that would break migration. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJZHMOuAAoJECgfDbjSjVRp/5IH/3kOa7yV3KUi4QVbQV7WwBH3 LK+/jwIz4UhOZn+bS4qi+gjN6aFhNoBNDFmYsRTWKKdLMvZvkRBMDcv8DMIKeAyl kG/ispv8VI+GY/CRKnqzPm0FSulv8WPRryxkdGzK4oHiMv+4FpFR0v/n9NRHjwTA XNJ4k33IqBldXyZwwAzP5dT019EMvbn4bNrkLzlcF2w8mTWPf43eX/kIkRX0cAys 5IVTQVGEOwpnyV0jxJDP+aoVMrqv8xl88LLuRpTgWUo0UnxXL5/GZQOCCUN6DQ7M BOLmyyP9mT9k8iUI+fQsDxAtY7cL9torq+p985nQdH0nxmI3GCoufn9aJG0J9yc= =d34x -----END PGP SIGNATURE----- Merge remote-tracking branch 'mst/tags/for_upstream' into staging pci, virtio, vhost: fixes A bunch of fixes that missed the release. Most notably we are reverting shpc back to enabled by default state as guests uses that as an indicator that hotplug is supported (even though it's unused). Unfortunately we can't fix this on the stable branch since that would break migration. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Wed 17 May 2017 10:42:06 PM BST # 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 * mst/tags/for_upstream: exec: abstract address_space_do_translate() pci: deassert intx when pci device unrealize virtio: allow broken device to notify guest Revert "hw/pci: disable pci-bridge's shpc by default" acpi-defs: clean up open brace usage ACPI: don't call acpi_pcihp_device_plug_cb on xen iommu: Don't crash if machine is not PC_MACHINE pc: add 2.10 machine type pc/fwcfg: unbreak migration from qemu-2.5 and qemu-2.6 during firmware boot libvhost-user: fix crash when rings aren't ready hw/virtio: fix vhost user fails to startup when MQ hw/arm/virt: generate 64-bit addressable ACPI objects hw/acpi-defs: replace leading X with x_ in FADT field names Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
adb354dd1e
@ -1031,6 +1031,11 @@ vu_queue_get_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int *in_bytes,
|
||||
idx = vq->last_avail_idx;
|
||||
|
||||
total_bufs = in_total = out_total = 0;
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
while ((rc = virtqueue_num_heads(dev, vq, idx)) > 0) {
|
||||
unsigned int max, num_bufs, indirect = 0;
|
||||
struct vring_desc *desc;
|
||||
@ -1121,11 +1126,16 @@ vu_queue_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int in_bytes,
|
||||
|
||||
/* Fetch avail_idx from VQ memory only when we really need to know if
|
||||
* guest has added some buffers. */
|
||||
int
|
||||
bool
|
||||
vu_queue_empty(VuDev *dev, VuVirtq *vq)
|
||||
{
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vq->shadow_avail_idx != vq->last_avail_idx) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return vring_avail_idx(vq) == vq->last_avail_idx;
|
||||
@ -1174,7 +1184,8 @@ vring_notify(VuDev *dev, VuVirtq *vq)
|
||||
void
|
||||
vu_queue_notify(VuDev *dev, VuVirtq *vq)
|
||||
{
|
||||
if (unlikely(dev->broken)) {
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1291,7 +1302,8 @@ vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz)
|
||||
struct vring_desc *desc;
|
||||
int rc;
|
||||
|
||||
if (unlikely(dev->broken)) {
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1445,7 +1457,8 @@ vu_queue_fill(VuDev *dev, VuVirtq *vq,
|
||||
{
|
||||
struct vring_used_elem uelem;
|
||||
|
||||
if (unlikely(dev->broken)) {
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1474,7 +1487,8 @@ vu_queue_flush(VuDev *dev, VuVirtq *vq, unsigned int count)
|
||||
{
|
||||
uint16_t old, new;
|
||||
|
||||
if (unlikely(dev->broken)) {
|
||||
if (unlikely(dev->broken) ||
|
||||
unlikely(!vq->vring.avail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -327,13 +327,13 @@ void vu_queue_set_notification(VuDev *dev, VuVirtq *vq, int enable);
|
||||
bool vu_queue_enabled(VuDev *dev, VuVirtq *vq);
|
||||
|
||||
/**
|
||||
* vu_queue_enabled:
|
||||
* vu_queue_empty:
|
||||
* @dev: a VuDev context
|
||||
* @vq: a VuVirtq queue
|
||||
*
|
||||
* Returns: whether the queue is empty.
|
||||
* Returns: true if the queue is empty or not ready.
|
||||
*/
|
||||
int vu_queue_empty(VuDev *dev, VuVirtq *vq);
|
||||
bool vu_queue_empty(VuDev *dev, VuVirtq *vq);
|
||||
|
||||
/**
|
||||
* vu_queue_notify:
|
||||
|
115
exec.c
115
exec.c
@ -463,42 +463,12 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
|
||||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write)
|
||||
{
|
||||
IOMMUTLBEntry iotlb = {0};
|
||||
MemoryRegionSection *section;
|
||||
MemoryRegion *mr;
|
||||
|
||||
for (;;) {
|
||||
AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
|
||||
section = address_space_lookup_region(d, addr, false);
|
||||
addr = addr - section->offset_within_address_space
|
||||
+ section->offset_within_region;
|
||||
mr = section->mr;
|
||||
|
||||
if (!mr->iommu_ops) {
|
||||
break;
|
||||
}
|
||||
|
||||
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
|
||||
if (!(iotlb.perm & (1 << is_write))) {
|
||||
iotlb.target_as = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
|
||||
| (addr & iotlb.addr_mask));
|
||||
as = iotlb.target_as;
|
||||
}
|
||||
|
||||
return iotlb;
|
||||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *xlat, hwaddr *plen,
|
||||
bool is_write)
|
||||
static MemoryRegionSection address_space_do_translate(AddressSpace *as,
|
||||
hwaddr addr,
|
||||
hwaddr *xlat,
|
||||
hwaddr *plen,
|
||||
bool is_write,
|
||||
bool is_mmio)
|
||||
{
|
||||
IOMMUTLBEntry iotlb;
|
||||
MemoryRegionSection *section;
|
||||
@ -506,7 +476,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
|
||||
for (;;) {
|
||||
AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
|
||||
section = address_space_translate_internal(d, addr, &addr, plen, true);
|
||||
section = address_space_translate_internal(d, addr, &addr, plen, is_mmio);
|
||||
mr = section->mr;
|
||||
|
||||
if (!mr->iommu_ops) {
|
||||
@ -518,19 +488,84 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
| (addr & iotlb.addr_mask));
|
||||
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
|
||||
if (!(iotlb.perm & (1 << is_write))) {
|
||||
mr = &io_mem_unassigned;
|
||||
break;
|
||||
goto translate_fail;
|
||||
}
|
||||
|
||||
as = iotlb.target_as;
|
||||
}
|
||||
|
||||
*xlat = addr;
|
||||
|
||||
return *section;
|
||||
|
||||
translate_fail:
|
||||
return (MemoryRegionSection) { .mr = &io_mem_unassigned };
|
||||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
hwaddr xlat, plen;
|
||||
|
||||
/* Try to get maximum page mask during translation. */
|
||||
plen = (hwaddr)-1;
|
||||
|
||||
/* This can never be MMIO. */
|
||||
section = address_space_do_translate(as, addr, &xlat, &plen,
|
||||
is_write, false);
|
||||
|
||||
/* Illegal translation */
|
||||
if (section.mr == &io_mem_unassigned) {
|
||||
goto iotlb_fail;
|
||||
}
|
||||
|
||||
/* Convert memory region offset into address space offset */
|
||||
xlat += section.offset_within_address_space -
|
||||
section.offset_within_region;
|
||||
|
||||
if (plen == (hwaddr)-1) {
|
||||
/*
|
||||
* We use default page size here. Logically it only happens
|
||||
* for identity mappings.
|
||||
*/
|
||||
plen = TARGET_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Convert to address mask */
|
||||
plen -= 1;
|
||||
|
||||
return (IOMMUTLBEntry) {
|
||||
.target_as = section.address_space,
|
||||
.iova = addr & ~plen,
|
||||
.translated_addr = xlat & ~plen,
|
||||
.addr_mask = plen,
|
||||
/* IOTLBs are for DMAs, and DMA only allows on RAMs. */
|
||||
.perm = IOMMU_RW,
|
||||
};
|
||||
|
||||
iotlb_fail:
|
||||
return (IOMMUTLBEntry) {0};
|
||||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *xlat, hwaddr *plen,
|
||||
bool is_write)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
MemoryRegionSection section;
|
||||
|
||||
/* This can be MMIO, so setup MMIO bit. */
|
||||
section = address_space_do_translate(as, addr, xlat, plen, is_write, true);
|
||||
mr = section.mr;
|
||||
|
||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
||||
*plen = MIN(page, *plen);
|
||||
}
|
||||
|
||||
*xlat = addr;
|
||||
return mr;
|
||||
}
|
||||
|
||||
|
@ -1600,6 +1600,33 @@ build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
|
||||
(void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
|
||||
}
|
||||
|
||||
/* Build xsdt table */
|
||||
void
|
||||
build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
int i;
|
||||
unsigned xsdt_entries_offset;
|
||||
AcpiXsdtDescriptorRev2 *xsdt;
|
||||
const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len);
|
||||
const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]);
|
||||
const size_t xsdt_len = sizeof(*xsdt) + table_data_len;
|
||||
|
||||
xsdt = acpi_data_push(table_data, xsdt_len);
|
||||
xsdt_entries_offset = (char *)xsdt->table_offset_entry - table_data->data;
|
||||
for (i = 0; i < table_offsets->len; ++i) {
|
||||
uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
|
||||
uint64_t xsdt_entry_offset = xsdt_entries_offset + xsdt_entry_size * i;
|
||||
|
||||
/* xsdt->table_offset_entry to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, xsdt_entry_size,
|
||||
ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
|
||||
}
|
||||
build_header(linker, table_data,
|
||||
(void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
|
||||
}
|
||||
|
||||
void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
|
||||
uint64_t len, int node, MemoryAffinityFlags flags)
|
||||
{
|
||||
|
@ -385,7 +385,10 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
dev, errp);
|
||||
}
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
|
||||
if (!xen_enabled()) {
|
||||
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
}
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
if (s->cpu_hotplug_legacy) {
|
||||
legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
|
||||
@ -408,8 +411,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
|
||||
dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
if (!xen_enabled()) {
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
}
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
|
||||
!s->cpu_hotplug_legacy) {
|
||||
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
|
||||
|
@ -364,12 +364,12 @@ static void acpi_dsdt_add_power_button(Aml *scope)
|
||||
|
||||
/* RSDP */
|
||||
static GArray *
|
||||
build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
|
||||
build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
|
||||
{
|
||||
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
|
||||
unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
|
||||
unsigned rsdt_pa_offset =
|
||||
(char *)&rsdp->rsdt_physical_address - rsdp_table->data;
|
||||
unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
|
||||
unsigned xsdt_pa_offset =
|
||||
(char *)&rsdp->xsdt_physical_address - rsdp_table->data;
|
||||
|
||||
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
|
||||
true /* fseg memory */);
|
||||
@ -381,8 +381,8 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
|
||||
|
||||
/* Address to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
|
||||
ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
|
||||
ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
|
||||
ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset);
|
||||
|
||||
/* Checksum to be filled by Guest linker */
|
||||
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
|
||||
@ -654,7 +654,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
|
||||
VirtMachineState *vms, unsigned dsdt_tbl_offset)
|
||||
{
|
||||
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
|
||||
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
|
||||
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
|
||||
uint16_t bootflags;
|
||||
|
||||
switch (vms->psci_conduit) {
|
||||
@ -680,7 +680,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
|
||||
|
||||
/* DSDT address to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
|
||||
|
||||
build_header(linker, table_data,
|
||||
@ -743,7 +743,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
{
|
||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||
GArray *table_offsets;
|
||||
unsigned dsdt, rsdt;
|
||||
unsigned dsdt, xsdt;
|
||||
GArray *tables_blob = tables->table_data;
|
||||
|
||||
table_offsets = g_array_new(false, true /* clear */,
|
||||
@ -783,12 +783,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
build_iort(tables_blob, tables->linker);
|
||||
}
|
||||
|
||||
/* RSDT is pointed to by RSDP */
|
||||
rsdt = tables_blob->len;
|
||||
build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
|
||||
/* XSDT is pointed to by RSDP */
|
||||
xsdt = tables_blob->len;
|
||||
build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
|
||||
|
||||
/* RSDP is in FSEG memory, so allocate it separately */
|
||||
build_rsdp(tables->rsdp, tables->linker, rsdt);
|
||||
build_rsdp(tables->rsdp, tables->linker, xsdt);
|
||||
|
||||
/* Cleanup memory that's no longer used. */
|
||||
g_array_free(table_offsets, true);
|
||||
|
@ -341,7 +341,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
|
||||
AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, sizeof(*fadt));
|
||||
unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
|
||||
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
|
||||
unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
|
||||
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
|
||||
|
||||
/* FACS address to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
@ -354,7 +354,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt),
|
||||
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
|
||||
|
||||
build_header(linker, table_data,
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/i386/amd_iommu.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "trace.h"
|
||||
|
||||
@ -1137,7 +1138,19 @@ static void amdvi_realize(DeviceState *dev, Error **err)
|
||||
int ret = 0;
|
||||
AMDVIState *s = AMD_IOMMU_DEVICE(dev);
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
|
||||
PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
PCMachineState *pcms =
|
||||
PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
|
||||
PCIBus *bus;
|
||||
|
||||
if (!pcms) {
|
||||
error_setg(err, "Machine-type '%s' not supported by amd-iommu",
|
||||
mc->name);
|
||||
return;
|
||||
}
|
||||
|
||||
bus = pcms->bus;
|
||||
s->iotlb = g_hash_table_new_full(amdvi_uint64_hash,
|
||||
amdvi_uint64_equal, g_free, g_free);
|
||||
|
||||
|
@ -2969,11 +2969,21 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
|
||||
|
||||
static void vtd_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
|
||||
PCIBus *bus = pcms->bus;
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
PCMachineState *pcms =
|
||||
PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
|
||||
PCIBus *bus;
|
||||
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
|
||||
|
||||
if (!pcms) {
|
||||
error_setg(errp, "Machine-type '%s' not supported by intel-iommu",
|
||||
mc->name);
|
||||
return;
|
||||
}
|
||||
|
||||
bus = pcms->bus;
|
||||
VTD_DPRINTF(GENERAL, "");
|
||||
x86_iommu->type = TYPE_INTEL;
|
||||
|
||||
|
@ -1049,12 +1049,10 @@ static void load_linux(PCMachineState *pcms,
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
|
||||
|
||||
if (fw_cfg_dma_enabled(fw_cfg)) {
|
||||
option_rom[nb_option_roms].bootindex = 0;
|
||||
option_rom[nb_option_roms].name = "linuxboot.bin";
|
||||
if (pcmc->linuxboot_dma_enabled && fw_cfg_dma_enabled(fw_cfg)) {
|
||||
option_rom[nb_option_roms].name = "linuxboot_dma.bin";
|
||||
option_rom[nb_option_roms].bootindex = 0;
|
||||
} else {
|
||||
option_rom[nb_option_roms].name = "linuxboot.bin";
|
||||
option_rom[nb_option_roms].bootindex = 0;
|
||||
}
|
||||
nb_option_roms++;
|
||||
}
|
||||
@ -2351,6 +2349,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
* to be used at the moment, 32K should be enough for a while. */
|
||||
pcmc->acpi_data_size = 0x20000 + 0x8000;
|
||||
pcmc->save_tsc_khz = true;
|
||||
pcmc->linuxboot_dma_enabled = true;
|
||||
mc->get_hotplug_handler = pc_get_hotpug_handler;
|
||||
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
|
||||
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
|
||||
|
@ -438,7 +438,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
|
||||
m->default_display = "std";
|
||||
}
|
||||
|
||||
static void pc_i440fx_2_9_machine_options(MachineClass *m)
|
||||
static void pc_i440fx_2_10_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_i440fx_machine_options(m);
|
||||
m->alias = "pc";
|
||||
@ -446,14 +446,23 @@ static void pc_i440fx_2_9_machine_options(MachineClass *m)
|
||||
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
|
||||
pc_i440fx_2_10_machine_options);
|
||||
|
||||
static void pc_i440fx_2_9_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_i440fx_2_10_machine_options(m);
|
||||
m->is_default = 0;
|
||||
m->alias = NULL;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
|
||||
pc_i440fx_2_9_machine_options);
|
||||
|
||||
static void pc_i440fx_2_8_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_i440fx_2_9_machine_options(m);
|
||||
m->is_default = 0;
|
||||
m->alias = NULL;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
|
||||
}
|
||||
|
||||
@ -476,6 +485,7 @@ static void pc_i440fx_2_6_machine_options(MachineClass *m)
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_i440fx_2_7_machine_options(m);
|
||||
pcmc->legacy_cpu_hotplug = true;
|
||||
pcmc->linuxboot_dma_enabled = false;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
|
||||
}
|
||||
|
||||
|
@ -302,20 +302,29 @@ static void pc_q35_machine_options(MachineClass *m)
|
||||
m->max_cpus = 288;
|
||||
}
|
||||
|
||||
static void pc_q35_2_9_machine_options(MachineClass *m)
|
||||
static void pc_q35_2_10_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_q35_machine_options(m);
|
||||
m->alias = "q35";
|
||||
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
|
||||
pc_q35_2_10_machine_options);
|
||||
|
||||
static void pc_q35_2_9_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_q35_2_10_machine_options(m);
|
||||
m->alias = NULL;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(v2_9, "pc-q35-2.9", NULL,
|
||||
pc_q35_2_9_machine_options);
|
||||
|
||||
static void pc_q35_2_8_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_q35_2_9_machine_options(m);
|
||||
m->alias = NULL;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
|
||||
}
|
||||
|
||||
@ -337,6 +346,7 @@ static void pc_q35_2_6_machine_options(MachineClass *m)
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_2_7_machine_options(m);
|
||||
pcmc->legacy_cpu_hotplug = true;
|
||||
pcmc->linuxboot_dma_enabled = false;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ static Property pci_bridge_dev_properties[] = {
|
||||
DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi,
|
||||
ON_OFF_AUTO_AUTO),
|
||||
DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags,
|
||||
PCI_BRIDGE_DEV_F_SHPC_REQ, false),
|
||||
PCI_BRIDGE_DEV_F_SHPC_REQ, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -1083,6 +1083,7 @@ static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
|
||||
pc->exit(pci_dev);
|
||||
}
|
||||
|
||||
pci_device_deassert_intx(pci_dev);
|
||||
do_pci_unregister_device(pci_dev);
|
||||
}
|
||||
|
||||
|
@ -163,22 +163,26 @@ fail:
|
||||
}
|
||||
|
||||
static int process_message_reply(struct vhost_dev *dev,
|
||||
VhostUserRequest request)
|
||||
VhostUserMsg msg)
|
||||
{
|
||||
VhostUserMsg msg;
|
||||
VhostUserMsg msg_reply;
|
||||
|
||||
if (vhost_user_read(dev, &msg) < 0) {
|
||||
if ((msg.flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vhost_user_read(dev, &msg_reply) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg.request != request) {
|
||||
if (msg_reply.request != msg.request) {
|
||||
error_report("Received unexpected msg type."
|
||||
"Expected %d received %d",
|
||||
request, msg.request);
|
||||
msg.request, msg_reply.request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return msg.payload.u64 ? -1 : 0;
|
||||
return msg_reply.payload.u64 ? -1 : 0;
|
||||
}
|
||||
|
||||
static bool vhost_user_one_time_request(VhostUserRequest request)
|
||||
@ -208,6 +212,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
|
||||
* request, we just ignore it.
|
||||
*/
|
||||
if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
|
||||
msg->flags &= ~VHOST_USER_NEED_REPLY_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -320,7 +325,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
|
||||
}
|
||||
|
||||
if (reply_supported) {
|
||||
return process_message_reply(dev, msg.request);
|
||||
return process_message_reply(dev, msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -712,7 +717,7 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu)
|
||||
|
||||
/* If reply_ack supported, slave has to ack specified MTU is valid */
|
||||
if (reply_supported) {
|
||||
return process_message_reply(dev, msg.request);
|
||||
return process_message_reply(dev, msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2451,12 +2451,12 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
|
||||
error_vreport(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
vdev->broken = true;
|
||||
|
||||
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
||||
virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
|
||||
virtio_notify_config(vdev);
|
||||
}
|
||||
|
||||
vdev->broken = true;
|
||||
}
|
||||
|
||||
static void virtio_memory_listener_commit(MemoryListener *listener)
|
||||
|
@ -81,8 +81,8 @@ typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
|
||||
uint32_t asl_compiler_revision; /* ASL compiler revision number */
|
||||
|
||||
|
||||
struct AcpiTableHeader /* ACPI common table header */
|
||||
{
|
||||
/* ACPI common table header */
|
||||
struct AcpiTableHeader {
|
||||
ACPI_TABLE_HEADER_DEF
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiTableHeader AcpiTableHeader;
|
||||
@ -144,8 +144,8 @@ typedef struct AcpiTableHeader AcpiTableHeader;
|
||||
/* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */ \
|
||||
uint16_t arm_boot_flags; \
|
||||
uint8_t minor_revision; /* FADT Minor Revision (ACPI 5.1) */ \
|
||||
uint64_t Xfacs; /* 64-bit physical address of FACS */ \
|
||||
uint64_t Xdsdt; /* 64-bit physical address of DSDT */ \
|
||||
uint64_t x_facs; /* 64-bit physical address of FACS */ \
|
||||
uint64_t x_dsdt; /* 64-bit physical address of DSDT */ \
|
||||
/* 64-bit Extended Power Mgt 1a Event Reg Blk address */ \
|
||||
struct AcpiGenericAddress xpm1a_event_block; \
|
||||
/* 64-bit Extended Power Mgt 1b Event Reg Blk address */ \
|
||||
@ -224,19 +224,27 @@ typedef struct AcpiSerialPortConsoleRedirection
|
||||
/*
|
||||
* ACPI 1.0 Root System Description Table (RSDT)
|
||||
*/
|
||||
struct AcpiRsdtDescriptorRev1
|
||||
{
|
||||
struct AcpiRsdtDescriptorRev1 {
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
uint32_t table_offset_entry[0]; /* Array of pointers to other */
|
||||
/* ACPI tables */
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
|
||||
|
||||
/*
|
||||
* ACPI 2.0 eXtended System Description Table (XSDT)
|
||||
*/
|
||||
struct AcpiXsdtDescriptorRev2 {
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
uint64_t table_offset_entry[0]; /* Array of pointers to other */
|
||||
/* ACPI tables */
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2;
|
||||
|
||||
/*
|
||||
* ACPI 1.0 Firmware ACPI Control Structure (FACS)
|
||||
*/
|
||||
struct AcpiFacsDescriptorRev1
|
||||
{
|
||||
struct AcpiFacsDescriptorRev1 {
|
||||
uint32_t signature; /* ACPI Signature */
|
||||
uint32_t length; /* Length of structure, in bytes */
|
||||
uint32_t hardware_signature; /* Hardware configuration signature */
|
||||
@ -262,8 +270,7 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
|
||||
|
||||
/* Master MADT */
|
||||
|
||||
struct AcpiMultipleApicTable
|
||||
{
|
||||
struct AcpiMultipleApicTable {
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
uint32_t local_apic_address; /* Physical address of local APIC */
|
||||
uint32_t flags;
|
||||
@ -299,8 +306,7 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
|
||||
|
||||
/* Sub-structures for MADT */
|
||||
|
||||
struct AcpiMadtProcessorApic
|
||||
{
|
||||
struct AcpiMadtProcessorApic {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint8_t processor_id; /* ACPI processor id */
|
||||
uint8_t local_apic_id; /* Processor's local APIC id */
|
||||
@ -308,8 +314,7 @@ struct AcpiMadtProcessorApic
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiMadtProcessorApic AcpiMadtProcessorApic;
|
||||
|
||||
struct AcpiMadtIoApic
|
||||
{
|
||||
struct AcpiMadtIoApic {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint8_t io_apic_id; /* I/O APIC ID */
|
||||
uint8_t reserved; /* Reserved - must be zero */
|
||||
@ -462,8 +467,7 @@ typedef struct Acpi20Hpet Acpi20Hpet;
|
||||
* SRAT (NUMA topology description) table
|
||||
*/
|
||||
|
||||
struct AcpiSystemResourceAffinityTable
|
||||
{
|
||||
struct AcpiSystemResourceAffinityTable {
|
||||
ACPI_TABLE_HEADER_DEF
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2[2];
|
||||
@ -475,8 +479,7 @@ typedef struct AcpiSystemResourceAffinityTable AcpiSystemResourceAffinityTable;
|
||||
#define ACPI_SRAT_PROCESSOR_x2APIC 2
|
||||
#define ACPI_SRAT_PROCESSOR_GICC 3
|
||||
|
||||
struct AcpiSratProcessorAffinity
|
||||
{
|
||||
struct AcpiSratProcessorAffinity {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint8_t proximity_lo;
|
||||
uint8_t local_apic_id;
|
||||
@ -498,8 +501,7 @@ struct AcpiSratProcessorX2ApicAffinity {
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiSratProcessorX2ApicAffinity AcpiSratProcessorX2ApicAffinity;
|
||||
|
||||
struct AcpiSratMemoryAffinity
|
||||
{
|
||||
struct AcpiSratMemoryAffinity {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint32_t proximity;
|
||||
uint16_t reserved1;
|
||||
@ -511,8 +513,7 @@ struct AcpiSratMemoryAffinity
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiSratMemoryAffinity AcpiSratMemoryAffinity;
|
||||
|
||||
struct AcpiSratProcessorGiccAffinity
|
||||
{
|
||||
struct AcpiSratProcessorGiccAffinity {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint32_t proximity;
|
||||
uint32_t acpi_processor_uid;
|
||||
|
@ -381,6 +381,9 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
|
||||
void
|
||||
build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
void
|
||||
build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
int
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...)
|
||||
|
@ -2,7 +2,11 @@
|
||||
#define HW_COMPAT_H
|
||||
|
||||
#define HW_COMPAT_2_9 \
|
||||
/* empty */
|
||||
{\
|
||||
.driver = "pci-bridge",\
|
||||
.property = "shpc",\
|
||||
.value = "off",\
|
||||
},
|
||||
|
||||
#define HW_COMPAT_2_8 \
|
||||
{\
|
||||
|
@ -151,6 +151,9 @@ struct PCMachineClass {
|
||||
bool save_tsc_khz;
|
||||
/* generate legacy CPU hotplug AML */
|
||||
bool legacy_cpu_hotplug;
|
||||
|
||||
/* use DMA capable linuxboot option rom */
|
||||
bool linuxboot_dma_enabled;
|
||||
};
|
||||
|
||||
#define TYPE_PC_MACHINE "generic-pc-machine"
|
||||
@ -379,6 +382,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
||||
int e820_get_num_entries(void);
|
||||
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
|
||||
#define PC_COMPAT_2_9 \
|
||||
HW_COMPAT_2_9 \
|
||||
|
||||
#define PC_COMPAT_2_8 \
|
||||
HW_COMPAT_2_8 \
|
||||
{\
|
||||
@ -438,10 +444,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
#define PC_COMPAT_2_6 \
|
||||
HW_COMPAT_2_6 \
|
||||
{\
|
||||
.driver = "fw_cfg_io",\
|
||||
.property = "dma_enabled",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = TYPE_X86_CPU,\
|
||||
.property = "cpuid-0xb",\
|
||||
.value = "off",\
|
||||
|
@ -175,8 +175,8 @@ static void test_acpi_fadt_table(test_data *data)
|
||||
ACPI_READ_FIELD(fadt_table->reset_value, addr);
|
||||
ACPI_READ_FIELD(fadt_table->arm_boot_flags, addr);
|
||||
ACPI_READ_FIELD(fadt_table->minor_revision, addr);
|
||||
ACPI_READ_FIELD(fadt_table->Xfacs, addr);
|
||||
ACPI_READ_FIELD(fadt_table->Xdsdt, addr);
|
||||
ACPI_READ_FIELD(fadt_table->x_facs, addr);
|
||||
ACPI_READ_FIELD(fadt_table->x_dsdt, addr);
|
||||
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_event_block, addr);
|
||||
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1b_event_block, addr);
|
||||
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_control_block, addr);
|
||||
|
Loading…
Reference in New Issue
Block a user