enum {
DEMU_OPT_DOMAIN,
- DEMU_OPT_VCPUS,
- DEMU_OPT_BUS,
DEMU_OPT_DEVICE,
DEMU_OPT_FUNCTION,
DEMU_NR_OPTS
static struct option demu_option[] = {
{"domain", 1, NULL, 0},
- {"vcpus", 1, NULL, 0},
- {"bus", 1, NULL, 0},
{"device", 1, NULL, 0},
{"function", 1, NULL, 0},
{NULL, 0, NULL, 0}
static const char *demu_option_text[] = {
"<domid>",
- "<vcpu count>",
- "<bus>",
"<device>",
"<function>",
NULL
DEMU_SEQ_SERVER_REGISTERED,
DEMU_SEQ_SHARED_IOPAGE_MAPPED,
DEMU_SEQ_BUFFERED_IOPAGE_MAPPED,
+ DEMU_SEQ_SERVER_ENABLED,
DEMU_SEQ_PORT_ARRAY_ALLOCATED,
DEMU_SEQ_EVTCHN_OPEN,
DEMU_SEQ_PORTS_BOUND,
DEMU_SEQ_BUF_PORT_BOUND,
+ DEMU_SEQ_DEVICE_INITIALIZED,
DEMU_SEQ_INITIALIZED,
DEMU_NR_SEQS
} demu_seq_t;
DBG("buffered_iopage = %p\n", demu_state.buffered_iopage);
break;
+ case DEMU_SEQ_SERVER_ENABLED:
+ DBG(">SERVER_ENABLED\n");
+ break;
+
case DEMU_SEQ_PORT_ARRAY_ALLOCATED:
DBG(">PORT_ARRAY_ALLOCATED\n");
break;
demu_state.buf_ioreq_local_port);
break;
+ case DEMU_SEQ_DEVICE_INITIALIZED:
+ DBG(">DEVICE_INITIALIZED\n");
+ break;
+
case DEMU_SEQ_INITIALIZED:
DBG(">INITIALIZED\n");
break;
{
if (demu_state.seq == DEMU_SEQ_INITIALIZED) {
DBG("<INITIALIZED\n");
+
+ demu_state.seq = DEMU_SEQ_DEVICE_INITIALIZED;
+ }
+
+ if (demu_state.seq == DEMU_SEQ_DEVICE_INITIALIZED) {
+ DBG("<DEVICE_INITIALIZED\n");
device_teardown();
demu_state.seq = DEMU_SEQ_PORTS_BOUND;
free(demu_state.ioreq_local_port);
+ demu_state.seq = DEMU_SEQ_SERVER_ENABLED;
+ }
+
+ if (demu_state.seq == DEMU_SEQ_SERVER_ENABLED) {
+ DBG("<SERVER_ENABLED\n");
+ (void) xc_hvm_set_ioreq_server_state(demu_state.xch,
+ demu_state.domid,
+ demu_state.ioservid,
+ 0);
+
demu_state.seq = DEMU_SEQ_BUFFERED_IOPAGE_MAPPED;
}
}
static int
-demu_initialize(domid_t domid, unsigned int vcpus, unsigned int bus,
- unsigned int device, unsigned int function)
+demu_initialize(domid_t domid, unsigned int device, unsigned int function)
{
int rc;
xc_dominfo_t dominfo;
int i;
demu_state.domid = domid;
- demu_state.vcpus = vcpus;
demu_state.xch = xc_interface_open(NULL, NULL, 0);
if (demu_state.xch == NULL)
if (rc < 0 || dominfo.domid != demu_state.domid)
goto fail2;
- rc = xc_hvm_create_ioreq_server(demu_state.xch, demu_state.domid, &demu_state.ioservid);
+ demu_state.vcpus = dominfo.max_vcpu_id + 1;
+
+ DBG("%d vCPU(s)\n", demu_state.vcpus);
+
+ rc = xc_hvm_create_ioreq_server(demu_state.xch, demu_state.domid, 1,
+ &demu_state.ioservid);
if (rc < 0)
goto fail3;
demu_seq_next();
+ rc = xc_hvm_set_ioreq_server_state(demu_state.xch,
+ demu_state.domid,
+ demu_state.ioservid,
+ 1);
+ if (rc != 0)
+ goto fail7;
+
+ demu_seq_next();
+
demu_state.ioreq_local_port = malloc(sizeof (evtchn_port_t) *
demu_state.vcpus);
if (demu_state.ioreq_local_port == NULL)
- goto fail7;
+ goto fail8;
for (i = 0; i < demu_state.vcpus; i++)
demu_state.ioreq_local_port[i] = -1;
demu_state.xceh = xc_evtchn_open(NULL, 0);
if (demu_state.xceh == NULL)
- goto fail8;
+ goto fail9;
demu_seq_next();
rc = xc_evtchn_bind_interdomain(demu_state.xceh, demu_state.domid,
port);
if (rc < 0)
- goto fail9;
+ goto fail10;
demu_state.ioreq_local_port[i] = rc;
}
rc = xc_evtchn_bind_interdomain(demu_state.xceh, demu_state.domid,
buf_port);
if (rc < 0)
- goto fail10;
+ goto fail11;
demu_state.buf_ioreq_local_port = rc;
demu_seq_next();
rc = device_initialize(demu_state.xch, demu_state.domid,
- demu_state.ioservid, bus, device, function);
+ demu_state.ioservid, 0, device, function);
if (rc < 0)
- goto fail11;
+ goto fail12;
+
+ demu_seq_next();
demu_seq_next();
assert(demu_state.seq == DEMU_SEQ_INITIALIZED);
return 0;
+fail12:
+ DBG("fail12\n");
+
fail11:
DBG("fail11\n");
main(int argc, char **argv, char **envp)
{
char *domain_str;
- char *vcpus_str;
- char *bus_str;
char *device_str;
char *function_str;
int index;
char *end;
domid_t domid;
- unsigned int vcpus;
- unsigned int bus;
unsigned int device;
unsigned int function;
sigset_t block;
prog = basename(argv[0]);
domain_str = NULL;
- vcpus_str = NULL;
- bus_str = NULL;
device_str = NULL;
function_str = NULL;
if (c == -1)
break;
+ if (c != 0) {
+ usage();
+ /*NOTREACHED*/
+ }
+
DBG("--%s = '%s'\n", demu_option[index].name, optarg);
- assert(c == 0);
switch (index) {
case DEMU_OPT_DOMAIN:
domain_str = optarg;
break;
- case DEMU_OPT_VCPUS:
- vcpus_str = optarg;
- break;
-
- case DEMU_OPT_BUS:
- bus_str = optarg;
- break;
-
case DEMU_OPT_DEVICE:
device_str = optarg;
break;
}
if (domain_str == NULL ||
- vcpus_str == NULL ||
- bus_str == NULL ||
- device_str == NULL ||
- function_str == NULL) {
+ device_str == NULL) {
usage();
/*NOTREACHED*/
}
exit(1);
}
- vcpus = (unsigned int)strtol(vcpus_str, &end, 0);
- if (*end != '\0') {
- fprintf(stderr, "invalid vcpu count '%s'\n", vcpus_str);
- exit(1);
- }
-
- bus = (unsigned int)strtol(bus_str, &end, 0);
- if (*end != '\0') {
- fprintf(stderr, "invalid bus '%s'\n", bus_str);
- exit(1);
- }
-
device = (unsigned int)strtol(device_str, &end, 0);
if (*end != '\0') {
- fprintf(stderr, "invalid vcpu count '%s'\n", device_str);
+ fprintf(stderr, "invalid device number '%s'\n", device_str);
exit(1);
}
- function = (unsigned int)strtol(function_str, &end, 0);
- if (*end != '\0') {
- fprintf(stderr, "invalid vcpu count '%s'\n", function_str);
- exit(1);
+ if (function_str != NULL) {
+ function = (unsigned int)strtol(function_str, &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr, "invalid function number '%s'\n", function_str);
+ exit(1);
+ }
+ } else {
+ function = 0;
}
sigfillset(&block);
sigprocmask(SIG_BLOCK, &block, NULL);
- rc = demu_initialize(domid, vcpus, bus, device, function);
+ rc = demu_initialize(domid, device, function);
if (rc < 0) {
demu_teardown();
exit(1);
DBG("%02x:%02x:%02x\n", info->bus, info->device, info->function);
- rc = xc_hvm_map_pcidev_to_ioreq_server(xch, domid, ioservid, pci.bdf);
+ rc = xc_hvm_map_pcidev_to_ioreq_server(xch, domid, ioservid,
+ 0, info->bus, info->device, info->function);
if (rc < 0)
goto fail2;
- rc = xc_hvm_pci_hotplug_enable(xch, domid, info->device);
- if (rc < 0)
- goto fail3;
-
return 0;
-fail3:
- DBG("fail3\n");
-
- (void) xc_hvm_unmap_pcidev_from_ioreq_server(xch, domid, ioservid,
- pci.bdf);
-
fail2:
DBG("fail2\n");
{
uint8_t bus = (pci.bdf >> 8) & 0xff;
uint8_t device = (pci.bdf >> 3) & 0x1f;
- uint8_t function= pci.bdf & 0x07;
+ uint8_t function = pci.bdf & 0x07;
DBG("%02x:%02x:%02x\n", bus, device, function);
- (void) xc_hvm_pci_hotplug_disable(pci.xch, pci.domid, device);
- (void) xc_hvm_unmap_pcidev_from_ioreq_server(pci.xch, pci.domid,
- pci.ioservid, pci.bdf);
+ (void) xc_hvm_unmap_pcidev_from_ioreq_server(pci.xch, pci.domid, pci.ioservid,
+ 0, bus, device, function);
}
int
pci.domid,
pci.ioservid,
bar->is_mmio,
- bar->addr);
+ bar->addr,
+ bar->addr + bar->size - 1);
}
static pci_bar_t *
pci.domid,
pci.ioservid,
bar->is_mmio,
- bar->addr);
+ bar->addr,
+ bar->addr + bar->size - 1);
if (bar->ops->unmap)
bar->ops->unmap(bar->priv);
{
uint64_t i;
uint32_t val;
- uint16_t bdf;
-
- val = ~(0u);
+ uint32_t sbdf;
- if (!(addr & (1ull << 31)))
- goto done;
+ sbdf = (uint32_t)(addr >> 32);
- bdf = (uint16_t)(addr >> 8);
+ val = ~(0u);
- if (bdf != pci.bdf)
+ if (sbdf != pci.bdf)
goto done;
addr &= 0xff;
- addr += size >> 16;
- size &= 0xffff;
val = 0;
for (i = 0; i < size; i++) {
{
uint64_t i;
uint8_t mask;
- uint16_t bdf;
-
- if (!(addr & (1ull << 31)))
- return;
+ uint32_t sbdf;
- bdf = (uint16_t)(addr >> 8);
+ sbdf = (uint16_t)(addr >> 32);
- if (bdf != pci.bdf)
+ if (sbdf != pci.bdf)
return;
addr &= 0xff;