Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20160121' …
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
pm215 committed Jan 21, 2016
2 parents 8344646 + 5a11d0f commit 0b0571d
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 195 deletions.
3 changes: 3 additions & 0 deletions MAINTAINERS
Expand Up @@ -273,9 +273,12 @@ F: */xen*
F: hw/char/xen_console.c
F: hw/display/xenfb.c
F: hw/net/xen_nic.c
F: hw/block/xen_*
F: hw/xen/
F: hw/xenpv/
F: hw/i386/xen/
F: include/hw/xen/
F: include/sysemu/xen-mapcache.h

Hosts:
------
Expand Down
8 changes: 7 additions & 1 deletion exec.c
Expand Up @@ -1510,6 +1510,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
RAMBlock *block;
RAMBlock *last_block = NULL;
ram_addr_t old_ram_size, new_ram_size;
Error *err = NULL;

old_ram_size = last_ram_offset() >> TARGET_PAGE_BITS;

Expand All @@ -1519,7 +1520,12 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
if (!new_block->host) {
if (xen_enabled()) {
xen_ram_alloc(new_block->offset, new_block->max_length,
new_block->mr);
new_block->mr, &err);
if (err) {
error_propagate(errp, err);
qemu_mutex_unlock_ramlist();
return -1;
}
} else {
new_block->host = phys_mem_alloc(new_block->max_length,
&new_block->mr->align);
Expand Down
5 changes: 3 additions & 2 deletions hw/display/xenfb.c
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions hw/i386/pc_piix.c
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions hw/i386/pc_q35.c
Expand Up @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions hw/i386/xen/xen_pvdevice.c
Expand Up @@ -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;

Expand All @@ -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[] = {
Expand All @@ -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;
Expand Down
149 changes: 72 additions & 77 deletions hw/xen/xen-host-pci-device.c
Expand Up @@ -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];
Expand All @@ -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++) {
Expand Down Expand Up @@ -129,97 +121,91 @@ 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)
{
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,
Expand Down Expand Up @@ -341,55 +327,64 @@ 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;
d->bus = bus;
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)
Expand Down
5 changes: 3 additions & 2 deletions hw/xen/xen-host-pci-device.h
Expand Up @@ -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);

Expand Down

0 comments on commit 0b0571d

Please sign in to comment.