pci, virtio, acpi: fixes for 2.6
Fixes all over the place. Most notably, fixes migration for systems with pci express bridges, and random crashes observed with virtio blk and scsi dataplane. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJXB2OKAAoJECgfDbjSjVRpcfkH/jRxiCmaC2hArYS+xK1HXJuf FUuI6JpbrvcuxdoNNm3E3BLM+vweYJ2JsVfY47l7zFcQVnBCmdRw4JMUetpqvt5C ekEwuokvWcSwdCT6y3mUW3euZ5iBoiFxYAvjwtM4p2Aut6urZUA3oeBSsSikGWJj itKsdeaaGN5bzC7BJYROUIs8VuK4VfIPpRBGF20smfMjXZq2liOnW7NK5mQ8BClg klXfLnZ39IdR+MQ37J1uo9TgY/HcdOGRK1KYezq+6nsO4jlAfGrDr99+D9bsheLJ G1jZLDEa+oTjfoCvqVkCK3+8O2vvHQe2BeR9sCEipYY9401gQPCqq4fmhv8/+O0= =U4yU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pci, virtio, acpi: fixes for 2.6 Fixes all over the place. Most notably, fixes migration for systems with pci express bridges, and random crashes observed with virtio blk and scsi dataplane. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 08 Apr 2016 08:53:46 BST using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: hw/pci-bridge: Add missing unref in case register-bus fails virtio: merge virtio_queue_aio_set_host_notifier_handler with virtio_queue_set_aio virtio-scsi: use aio handler for data plane virtio-blk: use aio handler for data plane virtio: add aio handler virtio-scsi: fix disabled mode virtio-blk: fix disabled mode virtio: make virtio_queue_notify_vq static tests/bios-tables-test: fix assert virtio-balloon: reset the statistic timer to load device Migration: Add i82801b11 migration data Sort the fw_cfg file list xen: piix reuse pci generic class init function pci-testdev: fast mmio support acpi: Add missing GCC_FMT_ATTR Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8227e2d167
@ -29,7 +29,6 @@
|
||||
struct VirtIOBlockDataPlane {
|
||||
bool starting;
|
||||
bool stopping;
|
||||
bool disabled;
|
||||
|
||||
VirtIOBlkConf *conf;
|
||||
|
||||
@ -185,6 +184,17 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||
|
||||
assert(s->dataplane);
|
||||
assert(s->dataplane_started);
|
||||
|
||||
virtio_blk_handle_vq(s, vq);
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
{
|
||||
@ -227,14 +237,15 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
|
||||
/* Get this show started by hooking up our callbacks */
|
||||
aio_context_acquire(s->ctx);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, true, true);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx,
|
||||
virtio_blk_data_plane_handle_output);
|
||||
aio_context_release(s->ctx);
|
||||
return;
|
||||
|
||||
fail_host_notifier:
|
||||
k->set_guest_notifiers(qbus->parent, 1, false);
|
||||
fail_guest_notifiers:
|
||||
s->disabled = true;
|
||||
vblk->dataplane_disabled = true;
|
||||
s->starting = false;
|
||||
vblk->dataplane_started = true;
|
||||
}
|
||||
@ -251,8 +262,8 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
}
|
||||
|
||||
/* Better luck next time. */
|
||||
if (s->disabled) {
|
||||
s->disabled = false;
|
||||
if (vblk->dataplane_disabled) {
|
||||
vblk->dataplane_disabled = false;
|
||||
vblk->dataplane_started = false;
|
||||
return;
|
||||
}
|
||||
@ -262,7 +273,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
aio_context_acquire(s->ctx);
|
||||
|
||||
/* Stop notifications for new requests from guest */
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, NULL);
|
||||
|
||||
/* Drain and switch bs back to the QEMU main loop */
|
||||
blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
|
||||
|
@ -54,7 +54,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
|
||||
|
||||
stb_p(&req->in->status, status);
|
||||
virtqueue_push(s->vq, &req->elem, req->in_len);
|
||||
if (s->dataplane) {
|
||||
if (s->dataplane_started && !s->dataplane_disabled) {
|
||||
virtio_blk_data_plane_notify(s->dataplane);
|
||||
} else {
|
||||
virtio_notify(vdev, s->vq);
|
||||
@ -578,20 +578,11 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
||||
VirtIOBlockReq *req;
|
||||
MultiReqBuffer mrb = {};
|
||||
|
||||
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
||||
* dataplane here instead of waiting for .set_status().
|
||||
*/
|
||||
if (s->dataplane && !s->dataplane_started) {
|
||||
virtio_blk_data_plane_start(s->dataplane);
|
||||
return;
|
||||
}
|
||||
|
||||
blk_io_plug(s->blk);
|
||||
|
||||
while ((req = virtio_blk_get_request(s))) {
|
||||
@ -605,6 +596,22 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
blk_io_unplug(s->blk);
|
||||
}
|
||||
|
||||
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||
|
||||
if (s->dataplane) {
|
||||
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
||||
* dataplane here instead of waiting for .set_status().
|
||||
*/
|
||||
virtio_blk_data_plane_start(s->dataplane);
|
||||
if (!s->dataplane_disabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_blk_handle_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_blk_dma_restart_bh(void *opaque)
|
||||
{
|
||||
VirtIOBlock *s = opaque;
|
||||
|
@ -1053,6 +1053,20 @@ void rom_set_fw(FWCfgState *f)
|
||||
fw_cfg = f;
|
||||
}
|
||||
|
||||
void rom_set_order_override(int order)
|
||||
{
|
||||
if (!fw_cfg)
|
||||
return;
|
||||
fw_cfg_set_order_override(fw_cfg, order);
|
||||
}
|
||||
|
||||
void rom_reset_order_override(void)
|
||||
{
|
||||
if (!fw_cfg)
|
||||
return;
|
||||
fw_cfg_reset_order_override(fw_cfg);
|
||||
}
|
||||
|
||||
static Rom *find_rom(hwaddr addr)
|
||||
{
|
||||
Rom *rom;
|
||||
|
@ -1406,6 +1406,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
{
|
||||
DeviceState *dev = NULL;
|
||||
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_VGA);
|
||||
if (pci_bus) {
|
||||
PCIDevice *pcidev = pci_vga_init(pci_bus);
|
||||
dev = pcidev ? &pcidev->qdev : NULL;
|
||||
@ -1413,6 +1414,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
ISADevice *isadev = isa_vga_init(isa_bus);
|
||||
dev = isadev ? DEVICE(isadev) : NULL;
|
||||
}
|
||||
rom_reset_order_override();
|
||||
return dev;
|
||||
}
|
||||
|
||||
@ -1541,6 +1543,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
{
|
||||
int i;
|
||||
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_NIC);
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
NICInfo *nd = &nd_table[i];
|
||||
|
||||
@ -1550,6 +1553,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
pci_nic_init_nofail(nd, pci_bus, "e1000", NULL);
|
||||
}
|
||||
}
|
||||
rom_reset_order_override();
|
||||
}
|
||||
|
||||
void pc_pci_device_init(PCIBus *pci_bus)
|
||||
|
@ -434,6 +434,7 @@ static void pc_i440fx_2_5_machine_options(MachineClass *m)
|
||||
m->alias = NULL;
|
||||
m->is_default = 0;
|
||||
pcmc->save_tsc_khz = false;
|
||||
m->legacy_fw_cfg_order = 1;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||
}
|
||||
|
||||
|
@ -298,6 +298,7 @@ static void pc_q35_2_5_machine_options(MachineClass *m)
|
||||
pc_q35_2_6_machine_options(m);
|
||||
m->alias = NULL;
|
||||
pcmc->save_tsc_khz = false;
|
||||
m->legacy_fw_cfg_order = 1;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||
}
|
||||
|
||||
|
@ -258,22 +258,10 @@ static const TypeInfo piix3_ide_info = {
|
||||
.class_init = piix3_ide_class_init,
|
||||
};
|
||||
|
||||
static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = pci_piix_ide_realize;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
|
||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
}
|
||||
|
||||
static const TypeInfo piix3_ide_xen_info = {
|
||||
.name = "piix3-ide-xen",
|
||||
.parent = TYPE_PCI_IDE,
|
||||
.class_init = piix3_ide_xen_class_init,
|
||||
.class_init = piix3_ide_class_init,
|
||||
};
|
||||
|
||||
static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
||||
|
@ -239,6 +239,7 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
||||
uint8_t *pci_conf;
|
||||
char *name;
|
||||
int r, i;
|
||||
bool fastmmio = kvm_ioeventfd_any_length_enabled();
|
||||
|
||||
pci_conf = pci_dev->config;
|
||||
|
||||
@ -261,8 +262,12 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
||||
memcpy(test->hdr->name, name, strlen(name) + 1);
|
||||
g_free(name);
|
||||
test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
|
||||
test->size = IOTEST_ACCESS_WIDTH;
|
||||
test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
|
||||
if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) {
|
||||
test->size = 0;
|
||||
} else {
|
||||
test->size = IOTEST_ACCESS_WIDTH;
|
||||
}
|
||||
test->hdr->test = i;
|
||||
test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
|
||||
test->hdr->width = IOTEST_ACCESS_WIDTH;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "hw/isa/isa.h"
|
||||
#include "hw/nvram/fw_cfg.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/boards.h"
|
||||
#include "trace.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/config-file.h"
|
||||
@ -69,11 +70,14 @@ struct FWCfgState {
|
||||
/*< public >*/
|
||||
|
||||
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
|
||||
int entry_order[FW_CFG_MAX_ENTRY];
|
||||
FWCfgFiles *files;
|
||||
uint16_t cur_entry;
|
||||
uint32_t cur_offset;
|
||||
Notifier machine_ready;
|
||||
|
||||
int fw_cfg_order_override;
|
||||
|
||||
bool dma_enabled;
|
||||
dma_addr_t dma_addr;
|
||||
AddressSpace *dma_as;
|
||||
@ -665,12 +669,87 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
|
||||
fw_cfg_add_bytes(s, key, copy, sizeof(value));
|
||||
}
|
||||
|
||||
void fw_cfg_set_order_override(FWCfgState *s, int order)
|
||||
{
|
||||
assert(s->fw_cfg_order_override == 0);
|
||||
s->fw_cfg_order_override = order;
|
||||
}
|
||||
|
||||
void fw_cfg_reset_order_override(FWCfgState *s)
|
||||
{
|
||||
assert(s->fw_cfg_order_override != 0);
|
||||
s->fw_cfg_order_override = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the legacy order list. For legacy systems, files are in
|
||||
* the fw_cfg in the order defined below, by the "order" value. Note
|
||||
* that some entries (VGA ROMs, NIC option ROMS, etc.) go into a
|
||||
* specific area, but there may be more than one and they occur in the
|
||||
* order that the user specifies them on the command line. Those are
|
||||
* handled in a special manner, using the order override above.
|
||||
*
|
||||
* For non-legacy, the files are sorted by filename to avoid this kind
|
||||
* of complexity in the future.
|
||||
*
|
||||
* This is only for x86, other arches don't implement versioning so
|
||||
* they won't set legacy mode.
|
||||
*/
|
||||
static struct {
|
||||
const char *name;
|
||||
int order;
|
||||
} fw_cfg_order[] = {
|
||||
{ "etc/boot-menu-wait", 10 },
|
||||
{ "bootsplash.jpg", 11 },
|
||||
{ "bootsplash.bmp", 12 },
|
||||
{ "etc/boot-fail-wait", 15 },
|
||||
{ "etc/smbios/smbios-tables", 20 },
|
||||
{ "etc/smbios/smbios-anchor", 30 },
|
||||
{ "etc/e820", 40 },
|
||||
{ "etc/reserved-memory-end", 50 },
|
||||
{ "genroms/kvmvapic.bin", 55 },
|
||||
{ "genroms/linuxboot.bin", 60 },
|
||||
{ }, /* VGA ROMs from pc_vga_init come here, 70. */
|
||||
{ }, /* NIC option ROMs from pc_nic_init come here, 80. */
|
||||
{ "etc/system-states", 90 },
|
||||
{ }, /* User ROMs come here, 100. */
|
||||
{ }, /* Device FW comes here, 110. */
|
||||
{ "etc/extra-pci-roots", 120 },
|
||||
{ "etc/acpi/tables", 130 },
|
||||
{ "etc/table-loader", 140 },
|
||||
{ "etc/tpm/log", 150 },
|
||||
{ "etc/acpi/rsdp", 160 },
|
||||
{ "bootorder", 170 },
|
||||
|
||||
#define FW_CFG_ORDER_OVERRIDE_LAST 200
|
||||
};
|
||||
|
||||
static int get_fw_cfg_order(FWCfgState *s, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s->fw_cfg_order_override > 0)
|
||||
return s->fw_cfg_order_override;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) {
|
||||
if (fw_cfg_order[i].name == NULL)
|
||||
continue;
|
||||
if (strcmp(name, fw_cfg_order[i].name) == 0)
|
||||
return fw_cfg_order[i].order;
|
||||
}
|
||||
/* Stick unknown stuff at the end. */
|
||||
error_report("warning: Unknown firmware file in legacy mode: %s\n", name);
|
||||
return FW_CFG_ORDER_OVERRIDE_LAST;
|
||||
}
|
||||
|
||||
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
FWCfgReadCallback callback, void *callback_opaque,
|
||||
void *data, size_t len)
|
||||
{
|
||||
int i, index;
|
||||
int i, index, count;
|
||||
size_t dsize;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||
int order = 0;
|
||||
|
||||
if (!s->files) {
|
||||
dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
|
||||
@ -678,13 +757,48 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
|
||||
}
|
||||
|
||||
index = be32_to_cpu(s->files->count);
|
||||
assert(index < FW_CFG_FILE_SLOTS);
|
||||
count = be32_to_cpu(s->files->count);
|
||||
assert(count < FW_CFG_FILE_SLOTS);
|
||||
|
||||
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name),
|
||||
filename);
|
||||
for (i = 0; i < index; i++) {
|
||||
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
||||
/* Find the insertion point. */
|
||||
if (mc->legacy_fw_cfg_order) {
|
||||
/*
|
||||
* Sort by order. For files with the same order, we keep them
|
||||
* in the sequence in which they were added.
|
||||
*/
|
||||
order = get_fw_cfg_order(s, filename);
|
||||
for (index = count;
|
||||
index > 0 && order < s->entry_order[index - 1];
|
||||
index--);
|
||||
} else {
|
||||
/* Sort by file name. */
|
||||
for (index = count;
|
||||
index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0;
|
||||
index--);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all the entries from the index point and after down one
|
||||
* to create a slot for the new entry. Because calculations are
|
||||
* being done with the index, make it so that "i" is the current
|
||||
* index and "i - 1" is the one being copied from, thus the
|
||||
* unusual start and end in the for statement.
|
||||
*/
|
||||
for (i = count + 1; i > index; i--) {
|
||||
s->files->f[i] = s->files->f[i - 1];
|
||||
s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
|
||||
s->entries[0][FW_CFG_FILE_FIRST + i] =
|
||||
s->entries[0][FW_CFG_FILE_FIRST + i - 1];
|
||||
s->entry_order[i] = s->entry_order[i - 1];
|
||||
}
|
||||
|
||||
memset(&s->files->f[index], 0, sizeof(FWCfgFile));
|
||||
memset(&s->entries[0][FW_CFG_FILE_FIRST + index], 0, sizeof(FWCfgEntry));
|
||||
|
||||
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name), filename);
|
||||
for (i = 0; i <= count; i++) {
|
||||
if (i != index &&
|
||||
strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
||||
error_report("duplicate fw_cfg file name: %s",
|
||||
s->files->f[index].name);
|
||||
exit(1);
|
||||
@ -696,9 +810,10 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||
|
||||
s->files->f[index].size = cpu_to_be32(len);
|
||||
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
|
||||
s->entry_order[index] = order;
|
||||
trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
|
||||
|
||||
s->files->count = cpu_to_be32(index+1);
|
||||
s->files->count = cpu_to_be32(count+1);
|
||||
}
|
||||
|
||||
void fw_cfg_add_file(FWCfgState *s, const char *filename,
|
||||
|
@ -78,6 +78,14 @@ err_bridge:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const VMStateDescription i82801b11_bridge_dev_vmstate = {
|
||||
.name = "i82801b11_bridge",
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
@ -89,6 +97,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
||||
k->revision = ICH9_D2P_A2_REVISION;
|
||||
k->init = i82801b11_bridge_initfn;
|
||||
k->config_write = pci_bridge_write_config;
|
||||
dc->vmsd = &i82801b11_bridge_dev_vmstate;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
||||
PCI_HOST_BRIDGE(ds)->bus = bus;
|
||||
|
||||
if (pxb_register_bus(dev, bus)) {
|
||||
return -EINVAL;
|
||||
goto err_register_bus;
|
||||
}
|
||||
|
||||
qdev_init_nofail(ds);
|
||||
@ -263,6 +263,12 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
||||
|
||||
pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
|
||||
return 0;
|
||||
|
||||
err_register_bus:
|
||||
object_unref(OBJECT(bds));
|
||||
object_unparent(OBJECT(bus));
|
||||
object_unref(OBJECT(ds));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pxb_dev_initfn(PCIDevice *dev)
|
||||
|
@ -38,7 +38,35 @@ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
|
||||
}
|
||||
}
|
||||
|
||||
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
||||
static void virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_cmd_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
|
||||
VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
assert(s->ctx && s->dataplane_started);
|
||||
virtio_scsi_handle_event_vq(s, vq);
|
||||
}
|
||||
|
||||
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
|
||||
void (*fn)(VirtIODevice *vdev, VirtQueue *vq))
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
@ -53,7 +81,7 @@ static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
||||
return rc;
|
||||
}
|
||||
|
||||
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, true, true);
|
||||
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, fn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -70,10 +98,10 @@ static void virtio_scsi_clear_aio(VirtIOSCSI *s)
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
||||
int i;
|
||||
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, NULL);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, NULL);
|
||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, false, false);
|
||||
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,16 +132,19 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s)
|
||||
}
|
||||
|
||||
aio_context_acquire(s->ctx);
|
||||
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0);
|
||||
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0,
|
||||
virtio_scsi_data_plane_handle_ctrl);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1);
|
||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
|
||||
virtio_scsi_data_plane_handle_event);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2);
|
||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
|
||||
virtio_scsi_data_plane_handle_cmd);
|
||||
if (rc) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
|
||||
|
||||
qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
|
||||
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
|
||||
if (s->dataplane_started) {
|
||||
if (s->dataplane_started && !s->dataplane_fenced) {
|
||||
virtio_scsi_dataplane_notify(vdev, req);
|
||||
} else {
|
||||
virtio_notify(vdev, vq);
|
||||
@ -374,7 +374,7 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
VirtIODevice *vdev = (VirtIODevice *)s;
|
||||
uint32_t type;
|
||||
@ -412,20 +412,28 @@ void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
VirtIOSCSIReq *req;
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||
virtio_scsi_handle_ctrl_req(s, req);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
|
||||
{
|
||||
/* Sense data is not in req->resp and is copied separately
|
||||
@ -508,7 +516,7 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
|
||||
virtio_scsi_complete_cmd_req(req);
|
||||
}
|
||||
|
||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
VirtIOSCSICommon *vs = &s->parent_obj;
|
||||
SCSIDevice *d;
|
||||
@ -550,7 +558,7 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
return true;
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
{
|
||||
SCSIRequest *sreq = req->sreq;
|
||||
if (scsi_req_enqueue(sreq)) {
|
||||
@ -560,17 +568,11 @@ void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
scsi_req_unref(sreq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
/* use non-QOM casts in the data path */
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
VirtIOSCSIReq *req, *next;
|
||||
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
|
||||
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
||||
@ -582,6 +584,20 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
/* use non-QOM casts in the data path */
|
||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_cmd_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_get_config(VirtIODevice *vdev,
|
||||
uint8_t *config)
|
||||
{
|
||||
@ -725,17 +741,24 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||
{
|
||||
if (s->events_dropped) {
|
||||
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
|
||||
if (s->ctx && !s->dataplane_started) {
|
||||
if (s->ctx) {
|
||||
virtio_scsi_dataplane_start(s);
|
||||
return;
|
||||
}
|
||||
if (s->events_dropped) {
|
||||
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
||||
if (!s->dataplane_fenced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
virtio_scsi_handle_event_vq(s, vq);
|
||||
}
|
||||
|
||||
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
||||
@ -773,7 +796,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
SCSIDevice *sd = SCSI_DEVICE(dev);
|
||||
|
||||
if (s->ctx && !s->dataplane_disabled) {
|
||||
if (s->ctx && !s->dataplane_fenced) {
|
||||
VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
|
||||
|
||||
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
||||
|
@ -426,6 +426,10 @@ static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f,
|
||||
|
||||
s->num_pages = qemu_get_be32(f);
|
||||
s->actual = qemu_get_be32(f);
|
||||
|
||||
if (balloon_stats_enabled(s)) {
|
||||
balloon_stats_change_timer(s, s->stats_poll_interval);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ struct VirtQueue
|
||||
|
||||
uint16_t vector;
|
||||
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||
void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||
VirtIODevice *vdev;
|
||||
EventNotifier guest_notifier;
|
||||
EventNotifier host_notifier;
|
||||
@ -1088,7 +1089,17 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
|
||||
virtio_queue_update_rings(vdev, n);
|
||||
}
|
||||
|
||||
void virtio_queue_notify_vq(VirtQueue *vq)
|
||||
static void virtio_queue_notify_aio_vq(VirtQueue *vq)
|
||||
{
|
||||
if (vq->vring.desc && vq->handle_aio_output) {
|
||||
VirtIODevice *vdev = vq->vdev;
|
||||
|
||||
trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
|
||||
vq->handle_aio_output(vdev, vq);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_queue_notify_vq(VirtQueue *vq)
|
||||
{
|
||||
if (vq->vring.desc && vq->handle_output) {
|
||||
VirtIODevice *vdev = vq->vdev;
|
||||
@ -1143,6 +1154,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
||||
vdev->vq[i].vring.num_default = queue_size;
|
||||
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
|
||||
vdev->vq[i].handle_output = handle_output;
|
||||
vdev->vq[i].handle_aio_output = NULL;
|
||||
|
||||
return &vdev->vq[i];
|
||||
}
|
||||
@ -1780,6 +1792,31 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
|
||||
return &vq->guest_notifier;
|
||||
}
|
||||
|
||||
static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
|
||||
{
|
||||
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||
if (event_notifier_test_and_clear(n)) {
|
||||
virtio_queue_notify_aio_vq(vq);
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
void (*handle_output)(VirtIODevice *,
|
||||
VirtQueue *))
|
||||
{
|
||||
if (handle_output) {
|
||||
vq->handle_aio_output = handle_output;
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
||||
virtio_queue_host_notifier_aio_read);
|
||||
} else {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
||||
/* Test and clear notifier before after disabling event,
|
||||
* in case poll callback didn't have time to run. */
|
||||
virtio_queue_host_notifier_aio_read(&vq->host_notifier);
|
||||
vq->handle_aio_output = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_queue_host_notifier_read(EventNotifier *n)
|
||||
{
|
||||
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||
@ -1788,22 +1825,6 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
bool assign, bool set_handler)
|
||||
{
|
||||
if (assign && set_handler) {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
||||
virtio_queue_host_notifier_read);
|
||||
} else {
|
||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
||||
}
|
||||
if (!assign) {
|
||||
/* Test and clear notifier before after disabling event,
|
||||
* in case poll callback didn't have time to run. */
|
||||
virtio_queue_host_notifier_read(&vq->host_notifier);
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||
bool set_handler)
|
||||
{
|
||||
|
@ -369,6 +369,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
int
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...);
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
#endif
|
||||
|
@ -108,7 +108,8 @@ struct MachineClass {
|
||||
no_cdrom:1,
|
||||
no_sdcard:1,
|
||||
has_dynamic_sysbus:1,
|
||||
pci_allow_0_address:1;
|
||||
pci_allow_0_address:1,
|
||||
legacy_fw_cfg_order:1;
|
||||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
|
@ -128,6 +128,8 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
size_t romsize, hwaddr addr);
|
||||
int rom_check_and_register_reset(void);
|
||||
void rom_set_fw(FWCfgState *f);
|
||||
void rom_set_order_override(int order);
|
||||
void rom_reset_order_override(void);
|
||||
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
||||
void *rom_ptr(hwaddr addr);
|
||||
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
||||
|
@ -11,6 +11,14 @@ typedef struct FWCfgFile {
|
||||
char name[FW_CFG_MAX_FILE_PATH];
|
||||
} FWCfgFile;
|
||||
|
||||
#define FW_CFG_ORDER_OVERRIDE_VGA 70
|
||||
#define FW_CFG_ORDER_OVERRIDE_NIC 80
|
||||
#define FW_CFG_ORDER_OVERRIDE_USER 100
|
||||
#define FW_CFG_ORDER_OVERRIDE_DEVICE 110
|
||||
|
||||
void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
|
||||
void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
|
||||
|
||||
typedef struct FWCfgFiles {
|
||||
uint32_t count;
|
||||
FWCfgFile f[];
|
||||
|
@ -53,6 +53,7 @@ typedef struct VirtIOBlock {
|
||||
unsigned short sector_mask;
|
||||
bool original_wce;
|
||||
VMChangeStateEntry *change;
|
||||
bool dataplane_disabled;
|
||||
bool dataplane_started;
|
||||
struct VirtIOBlockDataPlane *dataplane;
|
||||
} VirtIOBlock;
|
||||
@ -85,4 +86,6 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);
|
||||
|
||||
void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb);
|
||||
|
||||
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
|
||||
|
||||
#endif
|
||||
|
@ -91,7 +91,6 @@ typedef struct VirtIOSCSI {
|
||||
bool dataplane_started;
|
||||
bool dataplane_starting;
|
||||
bool dataplane_stopping;
|
||||
bool dataplane_disabled;
|
||||
bool dataplane_fenced;
|
||||
Error *blocker;
|
||||
uint32_t host_features;
|
||||
@ -140,9 +139,9 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
|
||||
HandleOutput cmd);
|
||||
|
||||
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_free_req(VirtIOSCSIReq *req);
|
||||
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
||||
|
@ -251,8 +251,8 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||
bool set_handler);
|
||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||
bool assign, bool set_handler);
|
||||
void virtio_queue_notify_vq(VirtQueue *vq);
|
||||
void (*fn)(VirtIODevice *,
|
||||
VirtQueue *));
|
||||
void virtio_irq(VirtQueue *vq);
|
||||
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
|
||||
VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
|
||||
|
@ -83,7 +83,7 @@ check-unit-y += tests/test-crypto-cipher$(EXESUF)
|
||||
check-unit-y += tests/test-crypto-secret$(EXESUF)
|
||||
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
|
||||
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
|
||||
check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
|
||||
#check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
|
||||
check-unit-y += tests/test-timed-average$(EXESUF)
|
||||
check-unit-y += tests/test-io-task$(EXESUF)
|
||||
check-unit-y += tests/test-io-channel-socket$(EXESUF)
|
||||
|
@ -432,7 +432,7 @@ static bool load_asl(GArray *sdts, AcpiSdtTable *sdt)
|
||||
|
||||
#define COMMENT_END "*/"
|
||||
#define DEF_BLOCK "DefinitionBlock ("
|
||||
#define BLOCK_NAME_END ".aml"
|
||||
#define BLOCK_NAME_END ","
|
||||
|
||||
static GString *normalize_asl(gchar *asl_code)
|
||||
{
|
||||
|
10
vl.c
10
vl.c
@ -2297,8 +2297,9 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
||||
gchar *buf;
|
||||
size_t size;
|
||||
const char *name, *file, *str;
|
||||
FWCfgState *fw_cfg = (FWCfgState *) opaque;
|
||||
|
||||
if (opaque == NULL) {
|
||||
if (fw_cfg == NULL) {
|
||||
error_report("fw_cfg device not available");
|
||||
return -1;
|
||||
}
|
||||
@ -2332,7 +2333,10 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
|
||||
/* For legacy, keep user files in a specific global order. */
|
||||
fw_cfg_set_order_override(fw_cfg, FW_CFG_ORDER_OVERRIDE_USER);
|
||||
fw_cfg_add_file(fw_cfg, name, buf, size);
|
||||
fw_cfg_reset_order_override(fw_cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4535,10 +4539,12 @@ int main(int argc, char **argv, char **envp)
|
||||
igd_gfx_passthru();
|
||||
|
||||
/* init generic devices */
|
||||
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
|
||||
if (qemu_opts_foreach(qemu_find_opts("device"),
|
||||
device_init_func, NULL, NULL)) {
|
||||
exit(1);
|
||||
}
|
||||
rom_reset_order_override();
|
||||
|
||||
/* Did we create any drives that we failed to create a device for? */
|
||||
drive_check_orphaned();
|
||||
|
Loading…
Reference in New Issue
Block a user