@@ -254,4 +254,5 @@ void vfio_user_set_reqhandler(VFIODevice *vbasdev,
VFIOUserFDs *fds),
void *reqarg);
int vfio_user_set_irqs(VFIODevice *vbasedev, struct vfio_irq_set *irq);
+void vfio_user_reset(VFIODevice *vbasedev);
#endif /* VFIO_USER_H */
@@ -2212,8 +2212,9 @@ static void vfio_pci_pre_reset(VFIOPCIDevice *vdev)
static void vfio_pci_post_reset(VFIOPCIDevice *vdev)
{
+ VFIODevice *vbasedev = &vdev->vbasedev;
Error *err = NULL;
- int nr;
+ int ret, nr;
vfio_intx_enable(vdev, &err);
if (err) {
@@ -2221,11 +2222,18 @@ static void vfio_pci_post_reset(VFIOPCIDevice *vdev)
}
for (nr = 0; nr < PCI_NUM_REGIONS - 1; ++nr) {
- off_t addr = vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr);
+ off_t addr = PCI_BASE_ADDRESS_0 + (4 * nr);
uint32_t val = 0;
uint32_t len = sizeof(val);
- if (pwrite(vdev->vbasedev.fd, &val, len, addr) != len) {
+ if (vbasedev->proxy != NULL) {
+ ret = vfio_user_region_write(vbasedev, VFIO_PCI_CONFIG_REGION_INDEX,
+ addr, len, &val);
+ } else {
+ ret = pwrite(vdev->vbasedev.fd, &val, len,
+ vdev->config_offset + addr);
+ }
+ if (ret != len) {
error_report("%s(%s) reset bar %d failed: %m", __func__,
vdev->vbasedev.name, nr);
}
@@ -3634,6 +3642,20 @@ static void vfio_user_instance_finalize(Object *obj)
vfio_user_disconnect(vbasedev->proxy);
}
+static void vfio_user_pci_reset(DeviceState *dev)
+{
+ VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
+ VFIODevice *vbasedev = &vdev->vbasedev;
+
+ vfio_pci_pre_reset(vdev);
+
+ if (vbasedev->reset_works) {
+ vfio_user_reset(vbasedev);
+ }
+
+ vfio_pci_post_reset(vdev);
+}
+
static Property vfio_user_pci_dev_properties[] = {
DEFINE_PROP_STRING("socket", VFIOUserPCIDevice, sock_name),
DEFINE_PROP_BOOL("secure-dma", VFIOUserPCIDevice, secure, false),
@@ -3645,6 +3667,7 @@ static void vfio_user_pci_dev_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
+ dc->reset = vfio_user_pci_reset;
device_class_set_props(dc, vfio_user_pci_dev_properties);
dc->desc = "VFIO over socket PCI device assignment";
pdc->realize = vfio_user_pci_realize;
@@ -905,3 +905,15 @@ int vfio_user_set_irqs(VFIODevice *vbasedev, struct vfio_irq_set *irq)
return 0;
}
+
+void vfio_user_reset(VFIODevice *vbasedev)
+{
+ vfio_user_hdr_t msg;
+
+ vfio_user_request_msg(&msg, VFIO_USER_DEVICE_RESET, sizeof(msg), 0);
+
+ vfio_user_send_recv(vbasedev->proxy, &msg, NULL, 0);
+ if (msg.flags & VFIO_USER_ERROR) {
+ error_printf("reset reply error %d\n", msg.error_reply);
+ }
+}