Skip to content

Commit

Permalink
multi-process: Retrieve PCI info from remote process
Browse files Browse the repository at this point in the history
Retrieve PCI configuration info about the remote device and
configure the Proxy PCI object based on the returned information

Signed-off-by: Elena Ufimtseva <[email protected]>
Signed-off-by: John G Johnson <[email protected]>
Signed-off-by: Jagannathan Raman <[email protected]>
Reviewed-by: Stefan Hajnoczi <[email protected]>
Message-id: 85ee367bbb993aa23699b44cfedd83b4ea6d5221.1611938319.git.jag.raman@oracle.com
Signed-off-by: Stefan Hajnoczi <[email protected]>
  • Loading branch information
jraman567 authored and stefanhaRH committed Feb 10, 2021
1 parent bd36adb commit 1bec145
Showing 1 changed file with 84 additions and 0 deletions.
84 changes: 84 additions & 0 deletions hw/remote/proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "sysemu/kvm.h"
#include "util/event_notifier-posix.c"

static void probe_pci_info(PCIDevice *dev, Error **errp);

static void proxy_intx_update(PCIDevice *pci_dev)
{
PCIProxyDev *dev = PCI_PROXY_DEV(pci_dev);
Expand Down Expand Up @@ -77,6 +79,7 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
{
ERRP_GUARD();
PCIProxyDev *dev = PCI_PROXY_DEV(device);
uint8_t *pci_conf = device->config;
int fd;

if (!dev->fd) {
Expand Down Expand Up @@ -106,9 +109,14 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
qemu_mutex_init(&dev->io_mutex);
qio_channel_set_blocking(dev->ioc, true, NULL);

pci_conf[PCI_LATENCY_TIMER] = 0xff;
pci_conf[PCI_INTERRUPT_PIN] = 0x01;

proxy_memory_listener_configure(&dev->proxy_listener, dev->ioc);

setup_irqfd(dev);

probe_pci_info(PCI_DEVICE(dev), errp);
}

static void pci_proxy_dev_exit(PCIDevice *pdev)
Expand Down Expand Up @@ -274,3 +282,79 @@ const MemoryRegionOps proxy_mr_ops = {
.max_access_size = 8,
},
};

static void probe_pci_info(PCIDevice *dev, Error **errp)
{
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
uint32_t orig_val, new_val, base_class, val;
PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
DeviceClass *dc = DEVICE_CLASS(pc);
uint8_t type;
int i, size;

config_op_send(pdev, PCI_VENDOR_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
pc->vendor_id = (uint16_t)val;

config_op_send(pdev, PCI_DEVICE_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
pc->device_id = (uint16_t)val;

config_op_send(pdev, PCI_CLASS_DEVICE, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
pc->class_id = (uint16_t)val;

config_op_send(pdev, PCI_SUBSYSTEM_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
pc->subsystem_id = (uint16_t)val;

base_class = pc->class_id >> 4;
switch (base_class) {
case PCI_BASE_CLASS_BRIDGE:
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
break;
case PCI_BASE_CLASS_STORAGE:
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
break;
case PCI_BASE_CLASS_NETWORK:
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
break;
case PCI_BASE_CLASS_INPUT:
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
break;
case PCI_BASE_CLASS_DISPLAY:
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
break;
case PCI_BASE_CLASS_PROCESSOR:
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
break;
default:
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
break;
}

for (i = 0; i < PCI_NUM_REGIONS; i++) {
config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
MPQEMU_CMD_PCI_CFGREAD);
new_val = 0xffffffff;
config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
MPQEMU_CMD_PCI_CFGWRITE);
config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
MPQEMU_CMD_PCI_CFGREAD);
size = (~(new_val & 0xFFFFFFF0)) + 1;
config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
MPQEMU_CMD_PCI_CFGWRITE);
type = (new_val & 0x1) ?
PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;

if (size) {
g_autofree char *name;
pdev->region[i].dev = pdev;
pdev->region[i].present = true;
if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
pdev->region[i].memory = true;
}
name = g_strdup_printf("bar-region-%d", i);
memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev),
&proxy_mr_ops, &pdev->region[i],
name, size);
pci_register_bar(dev, i, type, &pdev->region[i].mr);
}
}
}

0 comments on commit 1bec145

Please sign in to comment.