2 * Copyright © 2018, 2021 Oracle and/or its affiliates.
4 * This work is licensed under the terms of the GNU GPL, version 2 or later.
5 * See the COPYING file in the top-level directory.
9 #include "qemu/osdep.h"
10 #include "qemu-common.h"
12 #include "hw/remote/proxy.h"
13 #include "hw/pci/pci.h"
14 #include "qapi/error.h"
15 #include "io/channel-util.h"
16 #include "hw/qdev-properties.h"
17 #include "monitor/monitor.h"
18 #include "migration/blocker.h"
19 #include "qemu/sockets.h"
20 #include "hw/remote/mpqemu-link.h"
21 #include "qemu/error-report.h"
22 #include "hw/remote/proxy-memory-listener.h"
23 #include "qom/object.h"
24 #include "qemu/event_notifier.h"
25 #include "sysemu/kvm.h"
26 #include "util/event_notifier-posix.c"
28 static void probe_pci_info(PCIDevice
*dev
, Error
**errp
);
29 static void proxy_device_reset(DeviceState
*dev
);
31 static void proxy_intx_update(PCIDevice
*pci_dev
)
33 PCIProxyDev
*dev
= PCI_PROXY_DEV(pci_dev
);
35 int pin
= pci_get_byte(pci_dev
->config
+ PCI_INTERRUPT_PIN
) - 1;
37 if (dev
->virq
!= -1) {
38 kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state
, &dev
->intr
, dev
->virq
);
42 route
= pci_device_route_intx_to_irq(pci_dev
, pin
);
44 dev
->virq
= route
.irq
;
46 if (dev
->virq
!= -1) {
47 kvm_irqchip_add_irqfd_notifier_gsi(kvm_state
, &dev
->intr
,
48 &dev
->resample
, dev
->virq
);
52 static void setup_irqfd(PCIProxyDev
*dev
)
54 PCIDevice
*pci_dev
= PCI_DEVICE(dev
);
56 Error
*local_err
= NULL
;
58 event_notifier_init(&dev
->intr
, 0);
59 event_notifier_init(&dev
->resample
, 0);
61 memset(&msg
, 0, sizeof(MPQemuMsg
));
62 msg
.cmd
= MPQEMU_CMD_SET_IRQFD
;
64 msg
.fds
[0] = event_notifier_get_fd(&dev
->intr
);
65 msg
.fds
[1] = event_notifier_get_fd(&dev
->resample
);
68 if (!mpqemu_msg_send(&msg
, dev
->ioc
, &local_err
)) {
69 error_report_err(local_err
);
74 proxy_intx_update(pci_dev
);
76 pci_device_set_intx_routing_notifier(pci_dev
, proxy_intx_update
);
79 static void pci_proxy_dev_realize(PCIDevice
*device
, Error
**errp
)
82 PCIProxyDev
*dev
= PCI_PROXY_DEV(device
);
83 uint8_t *pci_conf
= device
->config
;
87 error_setg(errp
, "fd parameter not specified for %s",
92 fd
= monitor_fd_param(monitor_cur(), dev
->fd
, errp
);
94 error_prepend(errp
, "proxy: unable to parse fd %s: ", dev
->fd
);
98 if (!fd_is_socket(fd
)) {
99 error_setg(errp
, "proxy: fd %d is not a socket", fd
);
104 dev
->ioc
= qio_channel_new_fd(fd
, errp
);
110 error_setg(&dev
->migration_blocker
, "%s does not support migration",
112 if (migrate_add_blocker(dev
->migration_blocker
, errp
) < 0) {
113 error_free(dev
->migration_blocker
);
114 object_unref(dev
->ioc
);
118 qemu_mutex_init(&dev
->io_mutex
);
119 qio_channel_set_blocking(dev
->ioc
, true, NULL
);
121 pci_conf
[PCI_LATENCY_TIMER
] = 0xff;
122 pci_conf
[PCI_INTERRUPT_PIN
] = 0x01;
124 proxy_memory_listener_configure(&dev
->proxy_listener
, dev
->ioc
);
128 probe_pci_info(PCI_DEVICE(dev
), errp
);
131 static void pci_proxy_dev_exit(PCIDevice
*pdev
)
133 PCIProxyDev
*dev
= PCI_PROXY_DEV(pdev
);
136 qio_channel_close(dev
->ioc
, NULL
);
139 migrate_del_blocker(dev
->migration_blocker
);
141 error_free(dev
->migration_blocker
);
143 proxy_memory_listener_deconfigure(&dev
->proxy_listener
);
145 event_notifier_cleanup(&dev
->intr
);
146 event_notifier_cleanup(&dev
->resample
);
149 static void config_op_send(PCIProxyDev
*pdev
, uint32_t addr
, uint32_t *val
,
150 int len
, unsigned int op
)
152 MPQemuMsg msg
= { 0 };
153 uint64_t ret
= -EINVAL
;
154 Error
*local_err
= NULL
;
157 msg
.data
.pci_conf_data
.addr
= addr
;
158 msg
.data
.pci_conf_data
.val
= (op
== MPQEMU_CMD_PCI_CFGWRITE
) ? *val
: 0;
159 msg
.data
.pci_conf_data
.len
= len
;
160 msg
.size
= sizeof(PciConfDataMsg
);
162 ret
= mpqemu_msg_send_and_await_reply(&msg
, pdev
, &local_err
);
164 error_report_err(local_err
);
167 if (ret
== UINT64_MAX
) {
168 error_report("Failed to perform PCI config %s operation",
169 (op
== MPQEMU_CMD_PCI_CFGREAD
) ? "READ" : "WRITE");
172 if (op
== MPQEMU_CMD_PCI_CFGREAD
) {
173 *val
= (uint32_t)ret
;
177 static uint32_t pci_proxy_read_config(PCIDevice
*d
, uint32_t addr
, int len
)
181 config_op_send(PCI_PROXY_DEV(d
), addr
, &val
, len
, MPQEMU_CMD_PCI_CFGREAD
);
186 static void pci_proxy_write_config(PCIDevice
*d
, uint32_t addr
, uint32_t val
,
190 * Some of the functions access the copy of remote device's PCI config
191 * space which is cached in the proxy device. Therefore, maintain
194 pci_default_write_config(d
, addr
, val
, len
);
196 config_op_send(PCI_PROXY_DEV(d
), addr
, &val
, len
, MPQEMU_CMD_PCI_CFGWRITE
);
199 static Property proxy_properties
[] = {
200 DEFINE_PROP_STRING("fd", PCIProxyDev
, fd
),
201 DEFINE_PROP_END_OF_LIST(),
204 static void pci_proxy_dev_class_init(ObjectClass
*klass
, void *data
)
206 DeviceClass
*dc
= DEVICE_CLASS(klass
);
207 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
209 k
->realize
= pci_proxy_dev_realize
;
210 k
->exit
= pci_proxy_dev_exit
;
211 k
->config_read
= pci_proxy_read_config
;
212 k
->config_write
= pci_proxy_write_config
;
214 dc
->reset
= proxy_device_reset
;
216 device_class_set_props(dc
, proxy_properties
);
219 static const TypeInfo pci_proxy_dev_type_info
= {
220 .name
= TYPE_PCI_PROXY_DEV
,
221 .parent
= TYPE_PCI_DEVICE
,
222 .instance_size
= sizeof(PCIProxyDev
),
223 .class_init
= pci_proxy_dev_class_init
,
224 .interfaces
= (InterfaceInfo
[]) {
225 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
230 static void pci_proxy_dev_register_types(void)
232 type_register_static(&pci_proxy_dev_type_info
);
235 type_init(pci_proxy_dev_register_types
)
237 static void send_bar_access_msg(PCIProxyDev
*pdev
, MemoryRegion
*mr
,
238 bool write
, hwaddr addr
, uint64_t *val
,
239 unsigned size
, bool memory
)
241 MPQemuMsg msg
= { 0 };
243 Error
*local_err
= NULL
;
245 msg
.size
= sizeof(BarAccessMsg
);
246 msg
.data
.bar_access
.addr
= mr
->addr
+ addr
;
247 msg
.data
.bar_access
.size
= size
;
248 msg
.data
.bar_access
.memory
= memory
;
251 msg
.cmd
= MPQEMU_CMD_BAR_WRITE
;
252 msg
.data
.bar_access
.val
= *val
;
254 msg
.cmd
= MPQEMU_CMD_BAR_READ
;
257 ret
= mpqemu_msg_send_and_await_reply(&msg
, pdev
, &local_err
);
259 error_report_err(local_err
);
267 static void proxy_bar_write(void *opaque
, hwaddr addr
, uint64_t val
,
270 ProxyMemoryRegion
*pmr
= opaque
;
272 send_bar_access_msg(pmr
->dev
, &pmr
->mr
, true, addr
, &val
, size
,
276 static uint64_t proxy_bar_read(void *opaque
, hwaddr addr
, unsigned size
)
278 ProxyMemoryRegion
*pmr
= opaque
;
281 send_bar_access_msg(pmr
->dev
, &pmr
->mr
, false, addr
, &val
, size
,
287 const MemoryRegionOps proxy_mr_ops
= {
288 .read
= proxy_bar_read
,
289 .write
= proxy_bar_write
,
290 .endianness
= DEVICE_NATIVE_ENDIAN
,
292 .min_access_size
= 1,
293 .max_access_size
= 8,
297 static void probe_pci_info(PCIDevice
*dev
, Error
**errp
)
299 PCIDeviceClass
*pc
= PCI_DEVICE_GET_CLASS(dev
);
300 uint32_t orig_val
, new_val
, base_class
, val
;
301 PCIProxyDev
*pdev
= PCI_PROXY_DEV(dev
);
302 DeviceClass
*dc
= DEVICE_CLASS(pc
);
306 config_op_send(pdev
, PCI_VENDOR_ID
, &val
, 2, MPQEMU_CMD_PCI_CFGREAD
);
307 pc
->vendor_id
= (uint16_t)val
;
309 config_op_send(pdev
, PCI_DEVICE_ID
, &val
, 2, MPQEMU_CMD_PCI_CFGREAD
);
310 pc
->device_id
= (uint16_t)val
;
312 config_op_send(pdev
, PCI_CLASS_DEVICE
, &val
, 2, MPQEMU_CMD_PCI_CFGREAD
);
313 pc
->class_id
= (uint16_t)val
;
315 config_op_send(pdev
, PCI_SUBSYSTEM_ID
, &val
, 2, MPQEMU_CMD_PCI_CFGREAD
);
316 pc
->subsystem_id
= (uint16_t)val
;
318 base_class
= pc
->class_id
>> 4;
319 switch (base_class
) {
320 case PCI_BASE_CLASS_BRIDGE
:
321 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
323 case PCI_BASE_CLASS_STORAGE
:
324 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
326 case PCI_BASE_CLASS_NETWORK
:
327 case PCI_BASE_CLASS_WIRELESS
:
328 set_bit(DEVICE_CATEGORY_NETWORK
, dc
->categories
);
330 case PCI_BASE_CLASS_INPUT
:
331 set_bit(DEVICE_CATEGORY_INPUT
, dc
->categories
);
333 case PCI_BASE_CLASS_DISPLAY
:
334 set_bit(DEVICE_CATEGORY_DISPLAY
, dc
->categories
);
336 case PCI_BASE_CLASS_PROCESSOR
:
337 set_bit(DEVICE_CATEGORY_CPU
, dc
->categories
);
340 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
344 for (i
= 0; i
< PCI_NUM_REGIONS
; i
++) {
345 config_op_send(pdev
, PCI_BASE_ADDRESS_0
+ (4 * i
), &orig_val
, 4,
346 MPQEMU_CMD_PCI_CFGREAD
);
347 new_val
= 0xffffffff;
348 config_op_send(pdev
, PCI_BASE_ADDRESS_0
+ (4 * i
), &new_val
, 4,
349 MPQEMU_CMD_PCI_CFGWRITE
);
350 config_op_send(pdev
, PCI_BASE_ADDRESS_0
+ (4 * i
), &new_val
, 4,
351 MPQEMU_CMD_PCI_CFGREAD
);
352 size
= (~(new_val
& 0xFFFFFFF0)) + 1;
353 config_op_send(pdev
, PCI_BASE_ADDRESS_0
+ (4 * i
), &orig_val
, 4,
354 MPQEMU_CMD_PCI_CFGWRITE
);
355 type
= (new_val
& 0x1) ?
356 PCI_BASE_ADDRESS_SPACE_IO
: PCI_BASE_ADDRESS_SPACE_MEMORY
;
359 g_autofree
char *name
= g_strdup_printf("bar-region-%d", i
);
360 pdev
->region
[i
].dev
= pdev
;
361 pdev
->region
[i
].present
= true;
362 if (type
== PCI_BASE_ADDRESS_SPACE_MEMORY
) {
363 pdev
->region
[i
].memory
= true;
365 memory_region_init_io(&pdev
->region
[i
].mr
, OBJECT(pdev
),
366 &proxy_mr_ops
, &pdev
->region
[i
],
368 pci_register_bar(dev
, i
, type
, &pdev
->region
[i
].mr
);
373 static void proxy_device_reset(DeviceState
*dev
)
375 PCIProxyDev
*pdev
= PCI_PROXY_DEV(dev
);
376 MPQemuMsg msg
= { 0 };
377 Error
*local_err
= NULL
;
379 msg
.cmd
= MPQEMU_CMD_DEVICE_RESET
;
382 mpqemu_msg_send_and_await_reply(&msg
, pdev
, &local_err
);
384 error_report_err(local_err
);