From 1ab09b4a1a35f60a0c0efa5b04b0949336815e34 Mon Sep 17 00:00:00 2001 From: Alex Williamson <alex.williamson@redhat.com> Date: Wed, 23 Mar 2011 22:25:38 -0300 Subject: [PATCH 2/2] device-assignment: Reset device on system reset RH-Author: Alex Williamson <alex.williamson@redhat.com> Message-id: <20110323222538.3292.28939.stgit@s20.home> Patchwork-id: 20532 O-Subject: [RHEL5.7 qemu-kvm PATCH v2 2/2] device-assignment: Reset device on system reset Bugzilla: 657149 RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com> RH-Acked-by: Don Dutile <ddutile@redhat.com> RH-Acked-by: Michael S. Tsirkin <mst@redhat.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=657149 Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=3199413 Upstream status: posted (removed segment support and modified for backport) On system reset, we currently try to quiesce DMA by clearing the command register. This assumes that nothing re-enables bus master support without first de-programming the device. Use a bigger hammer to help the guest not shoot itself by issuing a function reset via sysfs on each system reset. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- qemu/hw/device-assignment.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- qemu/hw/device-assignment.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c index 81076c6..560887b 100644 --- a/qemu/hw/device-assignment.c +++ b/qemu/hw/device-assignment.c @@ -1177,6 +1177,25 @@ out: static void reset_assigned_device(void *opaque) { AssignedDevInfo *adev = opaque; + char reset_file[64]; + const char reset[] = "1"; + int fd, ret; + + snprintf(reset_file, sizeof(reset_file), + "/sys/bus/pci/devices/0000:%02x:%02x.%01x/reset", + adev->bus, adev->dev, adev->func); + + /* + * Issue a device reset via pci-sysfs. Note that we use write(2) here + * and ignore the return value because some kernels have a bug that + * returns 0 rather than bytes written on success, sending us into an + * infinite retry loop using other write mechanisms. + */ + fd = open(reset_file, O_WRONLY); + if (fd != -1) { + ret = write(fd, reset, strlen(reset)); + close(fd); + } /* * When a 0 is written to the command register, the device is logically -- 1.7.4.1.230.gae447