summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-01-21 17:21:08 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-01-21 17:21:08 +0000
commit0b0571dd246871f18b7d64b5279511e91e2a7bf6 (patch)
tree5fe918d7f97873791ac23f8e3bae64483b3f0ec2 /hw
parent83446463dd7b7e3d7e69bcaa079d6a5d8cd3cd76 (diff)
parent5a11d0f7549e24a10e178a9dc8ff5e698031d9a6 (diff)
downloadqemu-0b0571dd246871f18b7d64b5279511e91e2a7bf6.tar.gz
qemu-0b0571dd246871f18b7d64b5279511e91e2a7bf6.tar.bz2
qemu-0b0571dd246871f18b7d64b5279511e91e2a7bf6.zip
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20160121' into staging
Xen 2016/01/21 # gpg: Signature made Thu 21 Jan 2016 16:58:50 GMT using RSA key ID 70E1AE90 # gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" * remotes/sstabellini/tags/xen-20160121: Xen PCI passthru: convert to realize() Add Error **errp for xen_pt_config_init() Add Error **errp for xen_pt_setup_vga() Add Error **errp for xen_host_pci_device_get() Xen: use qemu_strtoul instead of strtol Change xen_host_pci_sysfs_path() to return void xen-pvdevice: convert to realize() xen-hvm: Clean up xen_ram_alloc() error handling xen-hvm: Clean up xen_hvm_init() error handling xenfb.c: avoid expensive loops when prod <= out_cons MAINTAINERS: update Xen files Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/display/xenfb.c5
-rw-r--r--hw/i386/pc_piix.c5
-rw-r--r--hw/i386/pc_q35.c5
-rw-r--r--hw/i386/xen/xen_pvdevice.c12
-rw-r--r--hw/xen/xen-host-pci-device.c149
-rw-r--r--hw/xen/xen-host-pci-device.h5
-rw-r--r--hw/xen/xen_pt.c77
-rw-r--r--hw/xen/xen_pt.h5
-rw-r--r--hw/xen/xen_pt_config_init.c51
-rw-r--r--hw/xen/xen_pt_graphics.c11
10 files changed, 168 insertions, 157 deletions
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 4e2a27a3d6..8eb3046244 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -789,8 +789,9 @@ static void xenfb_handle_events(struct XenFB *xenfb)
prod = page->out_prod;
out_cons = page->out_cons;
- if (prod == out_cons)
- return;
+ if (prod - out_cons >= XENFB_OUT_RING_LEN) {
+ return;
+ }
xen_rmb(); /* ensure we see ring contents up to prod */
for (cons = out_cons; cons != prod; cons++) {
union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 97219129ac..bc74557e35 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -121,9 +121,8 @@ static void pc_init1(MachineState *machine,
pcms->below_4g_mem_size = machine->ram_size;
}
- if (xen_enabled() && xen_hvm_init(pcms, &ram_memory) != 0) {
- fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
- exit(1);
+ if (xen_enabled()) {
+ xen_hvm_init(pcms, &ram_memory);
}
pc_cpus_init(pcms);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 8b76d5c94b..6128b0226d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -111,9 +111,8 @@ static void pc_q35_init(MachineState *machine)
pcms->below_4g_mem_size = machine->ram_size;
}
- if (xen_enabled() && xen_hvm_init(pcms, &ram_memory) != 0) {
- fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
- exit(1);
+ if (xen_enabled()) {
+ xen_hvm_init(pcms, &ram_memory);
}
pc_cpus_init(pcms);
diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c
index c2189473ba..9abcf25c1a 100644
--- a/hw/i386/xen/xen_pvdevice.c
+++ b/hw/i386/xen/xen_pvdevice.c
@@ -69,14 +69,16 @@ static const MemoryRegionOps xen_pv_mmio_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static int xen_pv_init(PCIDevice *pci_dev)
+static void xen_pv_realize(PCIDevice *pci_dev, Error **errp)
{
XenPVDevice *d = XEN_PV_DEVICE(pci_dev);
uint8_t *pci_conf;
/* device-id property must always be supplied */
- if (d->device_id == 0xffff)
- return -1;
+ if (d->device_id == 0xffff) {
+ error_setg(errp, "Device ID invalid, it must always be supplied");
+ return;
+ }
pci_conf = pci_dev->config;
@@ -97,8 +99,6 @@ static int xen_pv_init(PCIDevice *pci_dev)
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
&d->mmio);
-
- return 0;
}
static Property xen_pv_props[] = {
@@ -114,7 +114,7 @@ static void xen_pv_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = xen_pv_init;
+ k->realize = xen_pv_realize;
k->class_id = PCI_CLASS_SYSTEM_OTHER;
dc->desc = "Xen PV Device";
dc->props = xen_pv_props;
diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c
index 7d8a0237cf..3827ca7da7 100644
--- a/hw/xen/xen-host-pci-device.c
+++ b/hw/xen/xen-host-pci-device.c
@@ -31,25 +31,20 @@
#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
#define IORESOURCE_MEM_64 0x00100000
-static int xen_host_pci_sysfs_path(const XenHostPCIDevice *d,
- const char *name, char *buf, ssize_t size)
+static void xen_host_pci_sysfs_path(const XenHostPCIDevice *d,
+ const char *name, char *buf, ssize_t size)
{
int rc;
rc = snprintf(buf, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
d->domain, d->bus, d->dev, d->func, name);
-
- if (rc >= size || rc < 0) {
- /* The output is truncated, or some other error was encountered */
- return -ENODEV;
- }
- return 0;
+ assert(rc >= 0 && rc < size);
}
/* This size should be enough to read the first 7 lines of a resource file */
#define XEN_HOST_PCI_RESOURCE_BUFFER_SIZE 400
-static int xen_host_pci_get_resource(XenHostPCIDevice *d)
+static void xen_host_pci_get_resource(XenHostPCIDevice *d, Error **errp)
{
int i, rc, fd;
char path[PATH_MAX];
@@ -58,25 +53,22 @@ static int xen_host_pci_get_resource(XenHostPCIDevice *d)
char *endptr, *s;
uint8_t type;
- rc = xen_host_pci_sysfs_path(d, "resource", path, sizeof (path));
- if (rc) {
- return rc;
- }
+ xen_host_pci_sysfs_path(d, "resource", path, sizeof(path));
+
fd = open(path, O_RDONLY);
if (fd == -1) {
- XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
- return -errno;
+ error_setg_file_open(errp, errno, path);
+ return;
}
do {
- rc = read(fd, &buf, sizeof (buf) - 1);
+ rc = read(fd, &buf, sizeof(buf) - 1);
if (rc < 0 && errno != EINTR) {
- rc = -errno;
+ error_setg_errno(errp, errno, "read err");
goto out;
}
} while (rc < 0);
buf[rc] = 0;
- rc = 0;
s = buf;
for (i = 0; i < PCI_NUM_REGIONS; i++) {
@@ -129,70 +121,69 @@ static int xen_host_pci_get_resource(XenHostPCIDevice *d)
d->rom.bus_flags = flags & IORESOURCE_BITS;
}
}
+
if (i != PCI_NUM_REGIONS) {
- /* Invalid format or input to short */
- rc = -ENODEV;
+ error_setg(errp, "Invalid format or input too short: %s", buf);
}
out:
close(fd);
- return rc;
}
/* This size should be enough to read a long from a file */
#define XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE 22
-static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
- unsigned int *pvalue, int base)
+static void xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
+ unsigned int *pvalue, int base, Error **errp)
{
char path[PATH_MAX];
char buf[XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE];
int fd, rc;
unsigned long value;
- char *endptr;
+ const char *endptr;
+
+ xen_host_pci_sysfs_path(d, name, path, sizeof(path));
- rc = xen_host_pci_sysfs_path(d, name, path, sizeof (path));
- if (rc) {
- return rc;
- }
fd = open(path, O_RDONLY);
if (fd == -1) {
- XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
- return -errno;
+ error_setg_file_open(errp, errno, path);
+ return;
}
+
do {
- rc = read(fd, &buf, sizeof (buf) - 1);
+ rc = read(fd, &buf, sizeof(buf) - 1);
if (rc < 0 && errno != EINTR) {
- rc = -errno;
+ error_setg_errno(errp, errno, "read err");
goto out;
}
} while (rc < 0);
+
buf[rc] = 0;
- value = strtol(buf, &endptr, base);
- if (endptr == buf || *endptr != '\n') {
- rc = -1;
- } else if ((value == LONG_MIN || value == LONG_MAX) && errno == ERANGE) {
- rc = -errno;
- } else {
- rc = 0;
+ rc = qemu_strtoul(buf, &endptr, base, &value);
+ if (!rc) {
+ assert(value <= UINT_MAX);
*pvalue = value;
+ } else {
+ error_setg_errno(errp, -rc, "failed to parse value '%s'", buf);
}
+
out:
close(fd);
- return rc;
}
-static inline int xen_host_pci_get_hex_value(XenHostPCIDevice *d,
- const char *name,
- unsigned int *pvalue)
+static inline void xen_host_pci_get_hex_value(XenHostPCIDevice *d,
+ const char *name,
+ unsigned int *pvalue,
+ Error **errp)
{
- return xen_host_pci_get_value(d, name, pvalue, 16);
+ xen_host_pci_get_value(d, name, pvalue, 16, errp);
}
-static inline int xen_host_pci_get_dec_value(XenHostPCIDevice *d,
- const char *name,
- unsigned int *pvalue)
+static inline void xen_host_pci_get_dec_value(XenHostPCIDevice *d,
+ const char *name,
+ unsigned int *pvalue,
+ Error **errp)
{
- return xen_host_pci_get_value(d, name, pvalue, 10);
+ xen_host_pci_get_value(d, name, pvalue, 10, errp);
}
static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
@@ -200,26 +191,21 @@ static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
char path[PATH_MAX];
struct stat buf;
- if (xen_host_pci_sysfs_path(d, "physfn", path, sizeof (path))) {
- return false;
- }
+ xen_host_pci_sysfs_path(d, "physfn", path, sizeof(path));
+
return !stat(path, &buf);
}
-static int xen_host_pci_config_open(XenHostPCIDevice *d)
+static void xen_host_pci_config_open(XenHostPCIDevice *d, Error **errp)
{
char path[PATH_MAX];
- int rc;
- rc = xen_host_pci_sysfs_path(d, "config", path, sizeof (path));
- if (rc) {
- return rc;
- }
+ xen_host_pci_sysfs_path(d, "config", path, sizeof(path));
+
d->config_fd = open(path, O_RDWR);
- if (d->config_fd < 0) {
- return -errno;
+ if (d->config_fd == -1) {
+ error_setg_file_open(errp, errno, path);
}
- return 0;
}
static int xen_host_pci_config_read(XenHostPCIDevice *d,
@@ -341,11 +327,12 @@ int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *d, uint32_t cap)
return -1;
}
-int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
- uint8_t bus, uint8_t dev, uint8_t func)
+void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
+ uint8_t bus, uint8_t dev, uint8_t func,
+ Error **errp)
{
unsigned int v;
- int rc = 0;
+ Error *err = NULL;
d->config_fd = -1;
d->domain = domain;
@@ -353,43 +340,51 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
d->dev = dev;
d->func = func;
- rc = xen_host_pci_config_open(d);
- if (rc) {
+ xen_host_pci_config_open(d, &err);
+ if (err) {
goto error;
}
- rc = xen_host_pci_get_resource(d);
- if (rc) {
+
+ xen_host_pci_get_resource(d, &err);
+ if (err) {
goto error;
}
- rc = xen_host_pci_get_hex_value(d, "vendor", &v);
- if (rc) {
+
+ xen_host_pci_get_hex_value(d, "vendor", &v, &err);
+ if (err) {
goto error;
}
d->vendor_id = v;
- rc = xen_host_pci_get_hex_value(d, "device", &v);
- if (rc) {
+
+ xen_host_pci_get_hex_value(d, "device", &v, &err);
+ if (err) {
goto error;
}
d->device_id = v;
- rc = xen_host_pci_get_dec_value(d, "irq", &v);
- if (rc) {
+
+ xen_host_pci_get_dec_value(d, "irq", &v, &err);
+ if (err) {
goto error;
}
d->irq = v;
- rc = xen_host_pci_get_hex_value(d, "class", &v);
- if (rc) {
+
+ xen_host_pci_get_hex_value(d, "class", &v, &err);
+ if (err) {
goto error;
}
d->class_code = v;
+
d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
- return 0;
+ return;
+
error:
+ error_propagate(errp, err);
+
if (d->config_fd >= 0) {
close(d->config_fd);
d->config_fd = -1;
}
- return rc;
}
bool xen_host_pci_device_closed(XenHostPCIDevice *d)
diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h
index 3d44e044ff..6acf36e13a 100644
--- a/hw/xen/xen-host-pci-device.h
+++ b/hw/xen/xen-host-pci-device.h
@@ -36,8 +36,9 @@ typedef struct XenHostPCIDevice {
int config_fd;
} XenHostPCIDevice;
-int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
- uint8_t bus, uint8_t dev, uint8_t func);
+void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
+ uint8_t bus, uint8_t dev, uint8_t func,
+ Error **errp);
void xen_host_pci_device_put(XenHostPCIDevice *pci_dev);
bool xen_host_pci_device_closed(XenHostPCIDevice *d);
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index aa96288236..d33221be0e 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -760,13 +760,14 @@ static void xen_pt_destroy(PCIDevice *d) {
}
/* init */
-static int xen_pt_initfn(PCIDevice *d)
+static void xen_pt_realize(PCIDevice *d, Error **errp)
{
XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
- int rc = 0;
+ int i, rc = 0;
uint8_t machine_irq = 0, scratch;
uint16_t cmd = 0;
int pirq = XEN_PT_UNASSIGNED_PIRQ;
+ Error *err = NULL;
/* register real device */
XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d"
@@ -774,12 +775,14 @@ static int xen_pt_initfn(PCIDevice *d)
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
s->dev.devfn);
- rc = xen_host_pci_device_get(&s->real_device,
- s->hostaddr.domain, s->hostaddr.bus,
- s->hostaddr.slot, s->hostaddr.function);
- if (rc) {
- XEN_PT_ERR(d, "Failed to \"open\" the real pci device. rc: %i\n", rc);
- return -1;
+ xen_host_pci_device_get(&s->real_device,
+ s->hostaddr.domain, s->hostaddr.bus,
+ s->hostaddr.slot, s->hostaddr.function,
+ &err);
+ if (err) {
+ error_append_hint(&err, "Failed to \"open\" the real pci device");
+ error_propagate(errp, err);
+ return;
}
s->is_virtfn = s->real_device.is_virtfn;
@@ -799,16 +802,19 @@ static int xen_pt_initfn(PCIDevice *d)
if ((s->real_device.domain == 0) && (s->real_device.bus == 0) &&
(s->real_device.dev == 2) && (s->real_device.func == 0)) {
if (!is_igd_vga_passthrough(&s->real_device)) {
- XEN_PT_ERR(d, "Need to enable igd-passthru if you're trying"
- " to passthrough IGD GFX.\n");
+ error_setg(errp, "Need to enable igd-passthru if you're trying"
+ " to passthrough IGD GFX");
xen_host_pci_device_put(&s->real_device);
- return -1;
+ return;
}
- if (xen_pt_setup_vga(s, &s->real_device) < 0) {
- XEN_PT_ERR(d, "Setup VGA BIOS of passthrough GFX failed!\n");
+ xen_pt_setup_vga(s, &s->real_device, &err);
+ if (err) {
+ error_append_hint(&err, "Setup VGA BIOS of passthrough"
+ " GFX failed");
+ error_propagate(errp, err);
xen_host_pci_device_put(&s->real_device);
- return -1;
+ return;
}
/* Register ISA bridge for passthrough GFX. */
@@ -819,29 +825,30 @@ static int xen_pt_initfn(PCIDevice *d)
xen_pt_register_regions(s, &cmd);
/* reinitialize each config register to be emulated */
- rc = xen_pt_config_init(s);
- if (rc) {
- XEN_PT_ERR(d, "PCI Config space initialisation failed.\n");
+ xen_pt_config_init(s, &err);
+ if (err) {
+ error_append_hint(&err, "PCI Config space initialisation failed");
+ error_report_err(err);
+ rc = -1;
goto err_out;
}
/* Bind interrupt */
rc = xen_host_pci_get_byte(&s->real_device, PCI_INTERRUPT_PIN, &scratch);
if (rc) {
- XEN_PT_ERR(d, "Failed to read PCI_INTERRUPT_PIN! (rc:%d)\n", rc);
+ error_setg_errno(errp, errno, "Failed to read PCI_INTERRUPT_PIN");
goto err_out;
}
if (!scratch) {
- XEN_PT_LOG(d, "no pin interrupt\n");
+ error_setg(errp, "no pin interrupt");
goto out;
}
machine_irq = s->real_device.irq;
rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq);
-
if (rc < 0) {
- XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (err: %d)\n",
- machine_irq, pirq, errno);
+ error_setg_errno(errp, errno, "Mapping machine irq %u to"
+ " pirq %i failed", machine_irq, pirq);
/* Disable PCI intx assertion (turn on bit10 of devctl) */
cmd |= PCI_COMMAND_INTX_DISABLE;
@@ -862,8 +869,8 @@ static int xen_pt_initfn(PCIDevice *d)
PCI_SLOT(d->devfn),
e_intx);
if (rc < 0) {
- XEN_PT_ERR(d, "Binding of interrupt %i failed! (err: %d)\n",
- e_intx, errno);
+ error_setg_errno(errp, errno, "Binding of interrupt %u failed",
+ e_intx);
/* Disable PCI intx assertion (turn on bit10 of devctl) */
cmd |= PCI_COMMAND_INTX_DISABLE;
@@ -871,8 +878,8 @@ static int xen_pt_initfn(PCIDevice *d)
if (xen_pt_mapped_machine_irq[machine_irq] == 0) {
if (xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq)) {
- XEN_PT_ERR(d, "Unmapping of machine interrupt %i failed!"
- " (err: %d)\n", machine_irq, errno);
+ error_setg_errno(errp, errno, "Unmapping of machine"
+ " interrupt %u failed", machine_irq);
}
}
s->machine_irq = 0;
@@ -885,14 +892,14 @@ out:
rc = xen_host_pci_get_word(&s->real_device, PCI_COMMAND, &val);
if (rc) {
- XEN_PT_ERR(d, "Failed to read PCI_COMMAND! (rc: %d)\n", rc);
+ error_setg_errno(errp, errno, "Failed to read PCI_COMMAND");
goto err_out;
} else {
val |= cmd;
rc = xen_host_pci_set_word(&s->real_device, PCI_COMMAND, val);
if (rc) {
- XEN_PT_ERR(d, "Failed to write PCI_COMMAND val=0x%x!(rc: %d)\n",
- val, rc);
+ error_setg_errno(errp, errno, "Failed to write PCI_COMMAND"
+ " val = 0x%x", val);
goto err_out;
}
}
@@ -902,15 +909,19 @@ out:
memory_listener_register(&s->io_listener, &address_space_io);
s->listener_set = true;
XEN_PT_LOG(d,
- "Real physical device %02x:%02x.%d registered successfully!\n",
+ "Real physical device %02x:%02x.%d registered successfully\n",
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function);
- return 0;
+ return;
err_out:
+ for (i = 0; i < PCI_ROM_SLOT; i++) {
+ object_unparent(OBJECT(&s->bar[i]));
+ }
+ object_unparent(OBJECT(&s->rom));
+
xen_pt_destroy(d);
assert(rc);
- return rc;
}
static void xen_pt_unregister_device(PCIDevice *d)
@@ -929,7 +940,7 @@ static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = xen_pt_initfn;
+ k->realize = xen_pt_realize;
k->exit = xen_pt_unregister_device;
k->config_read = xen_pt_pci_read_config;
k->config_write = xen_pt_pci_write_config;
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 37497119f5..c2f8e1fc25 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -230,7 +230,7 @@ struct XenPCIPassthroughState {
bool listener_set;
};
-int xen_pt_config_init(XenPCIPassthroughState *s);
+void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp);
void xen_pt_config_delete(XenPCIPassthroughState *s);
XenPTRegGroup *xen_pt_find_reg_grp(XenPCIPassthroughState *s, uint32_t address);
XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t address);
@@ -330,5 +330,6 @@ static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
}
int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
-int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev);
+void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
+ Error **errp);
#endif /* !XEN_PT_H */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 185a698732..81c6721562 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1887,8 +1887,9 @@ static uint8_t find_cap_offset(XenPCIPassthroughState *s, uint8_t cap)
return 0;
}
-static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
- XenPTRegGroup *reg_grp, XenPTRegInfo *reg)
+static void xen_pt_config_reg_init(XenPCIPassthroughState *s,
+ XenPTRegGroup *reg_grp, XenPTRegInfo *reg,
+ Error **errp)
{
XenPTReg *reg_entry;
uint32_t data = 0;
@@ -1907,12 +1908,13 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
reg_grp->base_offset + reg->offset, &data);
if (rc < 0) {
g_free(reg_entry);
- return rc;
+ error_setg(errp, "Init emulate register fail");
+ return;
}
if (data == XEN_PT_INVALID_REG) {
/* free unused BAR register entry */
g_free(reg_entry);
- return 0;
+ return;
}
/* Sync up the data to dev.config */
offset = reg_grp->base_offset + reg->offset;
@@ -1930,7 +1932,8 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
if (rc) {
/* Serious issues when we cannot read the host values! */
g_free(reg_entry);
- return rc;
+ error_setg(errp, "Cannot read host values");
+ return;
}
/* Set bits in emu_mask are the ones we emulate. The dev.config shall
* contain the emulated view of the guest - therefore we flip the mask
@@ -1955,10 +1958,10 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
val = data;
if (val & ~size_mask) {
- XEN_PT_ERR(&s->dev,"Offset 0x%04x:0x%04x expands past register size(%d)!\n",
- offset, val, reg->size);
+ error_setg(errp, "Offset 0x%04x:0x%04x expands past"
+ " register size (%d)", offset, val, reg->size);
g_free(reg_entry);
- return -ENXIO;
+ return;
}
/* This could be just pci_set_long as we don't modify the bits
* past reg->size, but in case this routine is run in parallel or the
@@ -1978,13 +1981,12 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
}
/* list add register entry */
QLIST_INSERT_HEAD(&reg_grp->reg_tbl_list, reg_entry, entries);
-
- return 0;
}
-int xen_pt_config_init(XenPCIPassthroughState *s)
+void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp)
{
int i, rc;
+ Error *err = NULL;
QLIST_INIT(&s->reg_grps);
@@ -2027,11 +2029,12 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
reg_grp_offset,
&reg_grp_entry->size);
if (rc < 0) {
- XEN_PT_LOG(&s->dev, "Failed to initialize %d/%ld, type=0x%x, rc:%d\n",
- i, ARRAY_SIZE(xen_pt_emu_reg_grps),
+ error_setg(&err, "Failed to initialize %d/%zu, type = 0x%x,"
+ " rc: %d", i, ARRAY_SIZE(xen_pt_emu_reg_grps),
xen_pt_emu_reg_grps[i].grp_type, rc);
+ error_propagate(errp, err);
xen_pt_config_delete(s);
- return rc;
+ return;
}
}
@@ -2039,24 +2042,24 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
if (xen_pt_emu_reg_grps[i].emu_regs) {
int j = 0;
XenPTRegInfo *regs = xen_pt_emu_reg_grps[i].emu_regs;
+
/* initialize capability register */
for (j = 0; regs->size != 0; j++, regs++) {
- /* initialize capability register */
- rc = xen_pt_config_reg_init(s, reg_grp_entry, regs);
- if (rc < 0) {
- XEN_PT_LOG(&s->dev, "Failed to initialize %d/%ld reg 0x%x in grp_type=0x%x (%d/%ld), rc=%d\n",
- j, ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs),
- regs->offset, xen_pt_emu_reg_grps[i].grp_type,
- i, ARRAY_SIZE(xen_pt_emu_reg_grps), rc);
+ xen_pt_config_reg_init(s, reg_grp_entry, regs, &err);
+ if (err) {
+ error_append_hint(&err, "Failed to initialize %d/%zu"
+ " reg 0x%x in grp_type = 0x%x (%d/%zu)",
+ j, ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs),
+ regs->offset, xen_pt_emu_reg_grps[i].grp_type,
+ i, ARRAY_SIZE(xen_pt_emu_reg_grps));
+ error_propagate(errp, err);
xen_pt_config_delete(s);
- return rc;
+ return;
}
}
}
}
}
-
- return 0;
}
/* delete all emulate register */
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index df6069bf63..e7a7c7e263 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -161,7 +161,8 @@ struct pci_data {
uint16_t reserved;
} __attribute__((packed));
-int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev)
+void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
+ Error **errp)
{
unsigned char *bios = NULL;
struct rom_header *rom;
@@ -172,13 +173,14 @@ int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev)
struct pci_data *pd = NULL;
if (!is_igd_vga_passthrough(dev)) {
- return -1;
+ error_setg(errp, "Need to enable igd-passthrough");
+ return;
}
bios = get_vgabios(s, &bios_size, dev);
if (!bios) {
- XEN_PT_ERR(&s->dev, "VGA: Can't getting VBIOS!\n");
- return -1;
+ error_setg(errp, "VGA: Can't get VBIOS");
+ return;
}
/* Currently we fixed this address as a primary. */
@@ -203,7 +205,6 @@ int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev)
/* Currently we fixed this address as a primary for legacy BIOS. */
cpu_physical_memory_rw(0xc0000, bios, bios_size, 1);
- return 0;
}
uint32_t igd_read_opregion(XenPCIPassthroughState *s)