[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] pci-passthrough loses msi-x interrupts ability after domain destroy



Hi,

On Thu, Sep 21, 2017 at 07:09:12PM -0700, Christopher Clark wrote:
> On Thu, Sep 21, 2017 at 1:27 PM, Sander Eikelenboom
> <linux@xxxxxxxxxxxxxx> wrote:
> >
> > On Thu, September 21, 2017, 10:39:52 AM, Roger Pau Monné wrote:
> >
> >> On Wed, Sep 20, 2017 at 03:50:35PM -0400, Jérôme Oufella wrote:
> >>>
> >>> I'm using PCI pass-through to map a PCIe (intel i210) controller into
> >>> a HVM domain. The system uses xen-pciback to hide the appropriate PCI
> >>> device from Dom0.
> >>>
> >>> When creating the HVM domain after an hypervisor cold boot, the HVM
> >>> domain can access and use the PCIe controller without problem.
> >>>
> >>> However, if the HVM domain is destroyed then restarted, it won't be
> >>> able to use the pass-through PCI device anymore. The PCI device is
> >>> seen and can be mapped, however, the interrupts will not be passed to
> >>> the HVM domain anymore (this is visible under a Linux guest as
> >>> /proc/interrupts counters remain 0). The behavior on a Windows10 guest
> >>> is the same.
> >>>
> >>> A few interesting hints I noticed:
> >>>
> >>> - On Dom0, 'lspci -vv' on that PCIe device between the "working" and
> >>> the "muted interrupts" states, I noted a difference between the
> >>> MSI-X caps:
> >>>
> >>> - Capabilities: [70] MSI-X: Enable- Count=5 Masked- <-- IRQs will work if 
> >>> domain started
> >>> + Capabilities: [70] MSI-X: Enable- Count=5 Masked+ <-- IRQs won't work 
> >>> if domain started
> >>>                                             ^^^^^^^
> >
> >> IMHO it seems that either your device is not able to perform a reset
> >> successfully, or Linux is not correctly performing such reset. I don't
> >> think there's a lot that can be done from the Xen side.
> >
> > Unfortunately for a lot of pci-devices a simple reset as performed by 
> > default isn't enough,
> > but also almost none support a real pci FLR.
> >
> > In the distant past Konrad has made a patchset that implemented a bus reset 
> > and
> > reseting config space. (It piggy backed on already existing libxl mechanism 
> > of
> > trying to call on a syfs "do_flr" attribute which triggers pciback to 
> > perform
> > the busreset and rewrite of config space for the device.
> >
> > I use that patchset ever since for my pci-passtrough needs and it works 
> > pretty
> > well. I can shutdown an restart VM's with pci devices passed trhough (also 
> > AMD
> > Radeon graphic cards).
> 
> Just to confirm the utility of that piece of work: OpenXT also uses an
> extended version of that same patch to perform device reset for
> passthrough.
> 
> I've attached a copy of that OpenXT patch to this message and it can
> also be obtained from our git repository:
> https://github.com/OpenXT/xenclient-oe/blob/f8d3b282a87231d9ae717b13d506e8e7e28c78c4/recipes-kernel/linux/4.9/patches/thorough-reset-interface-to-pciback-s-sysfs.patch
> This version creates a sysfs node named "reset_device" and the OpenXT
> libxl toolstack is patched to use that node instead of "do_flr".
> 
> Konrad's original work encountered pushback on upstream acceptance at
> the time it was developed. I'm not sure I've found where that
> discussion ended. Is there any prospect of a more comprehensive reset
> mechanism being accepted into xen-pciback, or elsewhere in the kernel?
> 
> As noted in the original LKML threads, vfio has similar relevant pci
> device reset retry logic. (Thanks to Rich Persaud for this pointer:)
> http://elixir.free-electrons.com/linux/v4.14-rc1/source/drivers/vfio/pci/vfio_pci.c#L1353
> 
> libvirt also performs similar reset logic, using a direct low level
> interface to config space (Thanks to Marek for this pointer, libvirt
> is used by Qubes:)
> https://github.com/libvirt/libvirt/blob/master/src/util/virpci.c#L929
> I thinks this indicates that it would be possible to extend libxl to
> do something similar, but that seems less satisfactory compared to
> performing the work in a kernel-provided implementation.
> 
> Is there a way forward to providing this functionality within Xen
> software or Linux?
> 

Adding Konrad to CC ..


-- Pasi

> Christopher
> --
> 
> openxt.org

> From d686351d8ea4a1ea1d755d0a10f6f14d1c870911 Mon Sep 17 00:00:00 2001
> From: Kyle Temkin <ktemkin@xxxxxxxxxxxxxx>
> Date: Wed, 8 Apr 2015 00:58:24 -0400
> Subject: [PATCH] Add thorough reset interface to pciback's sysfs.
> 
> --------------------------------------------------------------------------------
> SHORT DESCRIPTION:
> --------------------------------------------------------------------------------
> Adds an interface that allows "more thorough" resets to be performed
> on devices which don't support Function Level Resets (FLRs). This
> interface should allow the toolstack to ensure that a PCI device is in a
> known state prior to passing it through to a VM.
> 
> --------------------------------------------------------------------------------
> LONG DESCRIPTION:
> --------------------------------------------------------------------------------
> 
> From Konrad Rzeszutek Wilk's original post to xen-devel and the LKML:
> 
>   The life-cycle of a PCI device in Xen pciback is complex
>   and is constrained by the PCI generic locking mechanism.
> 
>   It starts with the device being binded to us - for which
>   we do a device function reset (and done via SysFS
>   so the PCI lock is held)
> 
>   If the device is unbinded from us - we also do a function
>   reset (also done via SysFS so the PCI lock is held).
> 
>   If the device is un-assigned from a guest - we do a function
>   reset (no PCI lock).
> 
>   All on the individual PCI function level (so bus:device:function).
> 
>   Unfortunatly a function reset is not adequate for certain
>   PCIe devices. The reset for an individual PCI function "means
>   device must support FLR (PCIe or AF), PM reset on D3hot->D0
>   device specific reset, or be a singleton device on a bus
>   a secondary bus reset.  FLR does not have widespread support,
>   reset is not very reliable, and bus topology is dictated by the
>   and device design.  We need to provide a means for a user to
>   a bus reset in cases where the existing mechanisms are not
>    or not reliable. " (Adam Williamson, 'vfio-pci: PCI hot reset
>   interface' commit 8b27ee60bfd6bbb84d2df28fa706c5c5081066ca).
> 
>   As such to do a slot or a bus reset is we need another mechanism.
>   This is not exposed SysFS as there is no good way of exposing
>   a bus topology there.
> 
>   This is due to the complexity - we MUST know that the different
>   functions off a PCIe device are not in use by other drivers, or
>   if they are in use (say one of them is assigned to a guest
>   and the other is idle) - it is still OK to reset the slot
>   (assuming both of them are owned by Xen pciback).
> 
>   This patch does that by doing an slot or bus reset (if
>   slot not supported) if all of the functions of a PCIe
>   device belong to Xen PCIback. We do not care if the device is
>   in-use as we depend on the toolstack to be aware of this -
>   however if it is we will WARN the user.
> 
>   Due to the complexity with the PCI lock we cannot do
>   the reset when a device is binded ('echo $BDF > bind')
>   or when unbinded ('echo $BDF > unbind') as the pci_[slot|bus]_reset
>   also take the same lock resulting in a dead-lock.
> 
>   Putting the reset function in a workqueue or thread
>   won't work either - as we have to do the reset function
>   outside the 'unbind' context (it holds the PCI lock).
>   But once you 'unbind' a device the device is no longer
>   under the ownership of Xen pciback and the pci_set_drvdata
>   has been reset so we cannot use a thread for this.
> 
>   Instead of doing all this complex dance, we depend on the toolstack
>   doing the right thing. As such implement [... a SysFS attribute]
>   which [... the toolstack]  uses when a device is detached or attached
>   from/to a guest. It bypasses the need to worry about the PCI lock.
> 
>   To not inadvertly do a bus reset that would affect devices that
>   are in use by other drivers (other than Xen pciback) prior
>   to the reset we check that all of the devices under the bridge
>   are owned by Xen pciback. If they are not we do not do
>   the bus (or slot) reset.
> 
>   We also warn the user if the device is in use - but still
>   continue with the reset. This should not happen as the toolstack
>   also does the check.
> 
> --
> 
> Our version of the patch has been modified to use a less confusing
> sysfs name. The original name ('do_flr') is inappropriate, as it
> implies a function level reset; it is entirely possible that the patch
> code will use a bus-level reset when appropriate.
> 
> The new sysfs entry is located at:
> 
>   /sys/bus/pci/drivers/pciback/reset_device
> 
> and can be activated by writing a domain:bus:device:function device
> identifier into the sysfs file. As an example:
> 
>   echo "0000:01:00.0" > /sys/bus/pci/drivers/pciback/reset_device
> 
> would reset the device matching the D:BDF descriptor above.
> 
> --------------------------------------------------------------------------------
> CHANGELOG:
> --------------------------------------------------------------------------------
> This is a port of a patch that likely had many authors, including:
>     -Konrad Rzeszutek Wilk
>     -Alex Williamson
>     -Ross Phillipson <rphilipson@xxxxxxxxxxxx>
> Ported to OpenXT by: Kyle J. Temkin <temkink@xxxxxxxxxxxx>, 4/8/15
> Rewrite by:          Kyle J. Temkin <temkink@xxxxxxxxxxxx>, 4/10/15
> 
> --------------------------------------------------------------------------------
> DEPENDENCIES
> --------------------------------------------------------------------------------
> This patch requires ONE of the following:
>   -A relatively modern linux kernel (3.18+) as a base; which provides
>    the PCI functions used; or
>   -Our PCI reset backports patch (backport-pci-reset-functionality.patch),
>    which backports the relevant functionality to 3.11.
> 
> To take advantage of this patch, the utilized toolstack should be
> changed to:
>   -Use the provided "reset_device" property, rather than the PCI
>    device's sysfs "reset" entry. This enables resets beyond a FLR to be
>    used.
>   -Ensure that all functions of a given device are passed through
>    together. This allows us to use some of the more thorugh resetting
>    techniques, when possible.
> 
> --------------------------------------------------------------------------------
> REMOVAL
> --------------------------------------------------------------------------------
> This patch provides a service which is necessary for proper passthrough
> of many PCI cards: a generalized ability to reset PCI devices, without
> requiring that the device support FLR or power-management based resets.
> 
> This patch will be necessary until either the Linux PCI subsystem or Xen
> PCIback drivers are modified to provide this support; or until cards
> without proper FLR support are no longer supported.
> 
> --------------------------------------------------------------------------------
> UPSTREAM PLAN
> --------------------------------------------------------------------------------
> 
> This code is taken from a patch which was originally proposed and
> rejected from upstream on the LKML and xen-devel. An upstream
> implementation of the functionality of this patch is still necessary;
> and can and should be implemented.
> 
> This patch will hopefully be replaced with an upstream version when
> community concensus has produced a single "blessed" method of
> accomplishing its functionality.
> 
> --------------------------------------------------------------------------------
> PATCHES
> --------------------------------------------------------------------------------
> ---
>  drivers/xen/xen-pciback/pci_stub.c | 338 
> ++++++++++++++++++++++++++++++++++---
>  1 file changed, 312 insertions(+), 26 deletions(-)
> 
> Index: linux-4.9.40/drivers/xen/xen-pciback/pci_stub.c
> ===================================================================
> --- linux-4.9.40.orig/drivers/xen/xen-pciback/pci_stub.c
> +++ linux-4.9.40/drivers/xen/xen-pciback/pci_stub.c
> @@ -102,10 +102,9 @@ static void pcistub_device_release(struc
>  
>       xen_unregister_device_domain_owner(dev);
>  
> -     /* Call the reset function which does not take lock as this
> -      * is called from "unbind" which takes a device_lock mutex.
> -      */
> -     __pci_reset_function_locked(dev);
> +
> +     /* Reset is done by the toolstack by using 'reset_device' on the
> +      * SysFS. */
>       if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
>               dev_info(&dev->dev, "Could not reload PCI state\n");
>       else
> @@ -125,9 +124,6 @@ static void pcistub_device_release(struc
>                                err);
>       }
>  
> -     /* Disable the device */
> -     xen_pcibk_reset_device(dev);
> -
>       kfree(dev_data);
>       pci_set_drvdata(dev, NULL);
>  
> @@ -224,6 +220,271 @@ struct pci_dev *pcistub_get_pci_dev_by_s
>       return found_dev;
>  }
>  
> +
> +/**
> + * Returns true iff the given device supports PCIe FLRs.
> + */
> +static bool __device_supports_pcie_flr(struct pci_dev *dev)
> +{
> +     u32 cap;
> +
> +     /*
> +         * Read the device's capabilities. Note that this can be used even 
> on legacy
> +      * PCI devices (and not just on PCIe devices)-- it indicates that no 
> capabilities
> +      * are supported if the device is legacy PCI by setting cap to 0.
> +      */
> +      pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
> +
> +     /* Return true iff the device advertises supporting an FLR. */
> +     return (cap & PCI_EXP_DEVCAP_FLR);
> +}
> +
> +
> +/**
> + * Returns true iff the given device supports PCI Advanced Functionality 
> (AF) FLRs.
> + */
> +static bool __device_supports_pci_af_flr(struct pci_dev *dev)
> +{
> +     int pos;
> +     u8 capability_flags;
> +
> +     /* First, try to find the location of the PCI Advanced Functionality 
> capability byte. */
> +     pos = pci_find_capability(dev, PCI_CAP_ID_AF);
> +
> +     /*
> +      * If we weren't able to find the capability byte, this device doesn't 
> support
> +      * the Advanced Functionality extensions, and thus won't support AF FLR.
> +      */
> +     if (!pos)
> +             return false;
> +
> +     /* Read the capabilities advertised in the AF capability byte. */
> +     pci_read_config_byte(dev, pos + PCI_AF_CAP, &capability_flags);
> +
> +     /*
> +      * If the device does support AF, it will advertise FLR support via the
> +      * PCI_AF_CAP_FLR bit. We'll also check for the Transactions Pending 
> (TP)
> +      * mechanism, as the kernel requires this extension to issue an AF FLR.
> +      * (Internally, the PCI reset code needs to be able to wait for all
> +      * pending transactions to complete prior to issuing the AF FLR.)
> +      */
> +     return (capability_flags & PCI_AF_CAP_TP) && (capability_flags & 
> PCI_AF_CAP_FLR);
> +}
> +
> +
> +/**
> + * Returns true iff the given device adverstises supporting function-
> + * level-reset (FLR).
> + */
> +static bool device_supports_flr(struct pci_dev *dev)
> +{
> +     return __device_supports_pci_af_flr(dev) || 
> __device_supports_pcie_flr(dev);
> +}
> +
> +
> +/**
> + * Returns true iff the given device is located in a slot that
> + * supports hotplugging slot resets.
> + */
> +static bool device_supports_slot_reset(struct pci_dev *dev)
> +{
> +     return !pci_probe_reset_slot(dev->slot);
> +}
> +
> +
> +/**
> + * Returns true iff the given device is located on a bus that
> + * we can reset. Note that root bridges are excluded, as this
> + * would cause more than just an SBR.
> + */
> +static bool device_supports_bus_reset(struct pci_dev *dev)
> +{
> +     return !pci_is_root_bus(dev->bus) && !pci_probe_reset_bus(dev->bus);
> +}
> +
> +
> +/**
> + * Out argument for the __safe_to_sbr_device_callback function.
> + */
> +struct safe_to_sbr_arguments {
> +
> +     //Stores the most recently encountered PCI device that does
> +     //not belong to pciback. As used below, this is the result of a
> +     //search for a non-pciback device on a bus; we stop upon finding
> +     //the first non-pciback device.
> +     struct pci_dev *last_non_pciback_device;
> +
> +     //Stores the number of pciback devices that appear to be in use
> +     //on the bus in question.
> +     int use_count;
> +
> +};
> +
> +
> +/**
> + *   A callback function which determines if a given PCI device is owned by 
> pciback,
> + *   and whether the given device is in use. Used by safe_to_sbr_device.
> + *
> + *   @param dev The PCI device to be checked.
> + *   @param data An out argument of type struct 
> safe_to_sbr_device_callback_arguments.
> + *                   Updated to indicate the result of the search. See the 
> struct's definition
> + *                   for more details.
> + *
> + */
> +static int __safe_to_sbr_device_callback(struct pci_dev *dev, void *data)
> +{
> +
> +     struct pcistub_device *psdev;
> +
> +     bool device_owned_by_pciback = false;
> +     struct safe_to_sbr_arguments *arg = data;
> +
> +     unsigned long flags;
> +
> +     //Ensure that we have exclusive access to the list of PCI devices,
> +     //so we can traverse it.
> +     spin_lock_irqsave(&pcistub_devices_lock, flags);
> +
> +     //Iterate over all PCI devices owned by the pci stub.
> +     list_for_each_entry(psdev, &pcistub_devices, dev_list) {
> +
> +             //If the given device is owned by pciback...
> +             if (psdev->dev == dev) {
> +
> +                     //mark it as a pciback device.
> +                     device_owned_by_pciback = true;
> +
> +                     //If we have a physical device associated with the 
> pciback device,
> +                     //mark this device as in-use.
> +                     if (psdev->pdev)
> +                             arg->use_count++;
> +
> +                     //Stop searching; we've found a the PCIback device 
> associated with this one.
> +                     break;
> +             }
> +     }
> +
> +     //Release the PCI device lock...
> +     spin_unlock_irqrestore(&pcistub_devices_lock, flags);
> +
> +     //... and report if we've found a device that's not owned by pciback.
> +     dev_dbg(&dev->dev, "%s\n", device_owned_by_pciback ? "is owned by 
> pciback, and can be reset if not in use."
> +                     : "not owned by pciback, and thus cannot be reset.");
> +
> +     //If we've found a device that's not owned by pciback, update our data
> +     //argument so it points to the most recent unowned device. (We check
> +     //this like a flag, later: if it's never set, no one owns the device!)
> +     if (!device_owned_by_pciback)
> +             arg->last_non_pciback_device = dev;
> +
> +     //If we've found a device that's not owned by pciback, return false--
> +     //this indicates that pci_walk_bus should cease its walk.
> +     return !device_owned_by_pciback;
> +}
> +
> +
> +/**
> + * Returns true iff it should be safe to issue a secondary bus reset
> + * to the device; that is, if an SBR can be issued without disrupting
> + * other devices.
> + */
> +static bool safe_to_sbr_device(struct pci_dev *dev)
> +{
> +     struct safe_to_sbr_arguments walk_result = { .last_non_pciback_device = 
> NULL, .use_count = 0 };
> +
> +     //Walk the PCI bus, attempting to find if any of the given devices
> +     pci_walk_bus(dev->bus, __safe_to_sbr_device_callback, &walk_result);
> +
> +     //If the device is in use, emit a warning error.
> +     if(walk_result.use_count > 0)
> +             dev_dbg(&dev->dev, "is in use; currently not safe to SBR 
> device.\n");
> +
> +     //Return true iff we did not pick up any other devices
> +     //that were either in use, or not owned by pciback.
> +     return (walk_result.last_non_pciback_device == NULL) && 
> (walk_result.use_count == 0);
> +}
> +
> +
> +/**
> + * Attempt a raw reset of the provided PCI device-- via any
> + * method available to us. This method prefers the gentlest
> + * possible reset method-- currently an FLR, which many
> + * PCIe devices should support.
> + *
> + * @param dev The pci device to be reset.
> + * @return Zero on success, or the error code generated by the reset method 
> on failure.
> + */
> +static int __pcistub_raw_device_reset(struct pci_dev *dev)
> +{
> +     //Determine if bus resetting techniques (SBR, slot resets)
> +     //are safe, and thus should be allowed.
> +     int allow_bus_reset = safe_to_sbr_device(dev);
> +
> +     //If FLRs are supported; we'll try to let the linux kernel
> +     //manually reset the device.
> +     if(device_supports_flr(dev)) {
> +             dev_dbg(&dev->dev, "Resetting device using an FLR.");
> +             return pci_reset_function(dev);
> +     }
> +
> +     //Next, we'll try the next gentlest: a hotplugging reset
> +     //of the PCI slot.
> +     if(allow_bus_reset && device_supports_slot_reset(dev)) {
> +             dev_dbg(&dev->dev, "Resetting device using a slot reset.");
> +             return pci_try_reset_slot(dev->slot);
> +     }
> +
> +     //Finally, we'll try the most drastic: resetting the parent
> +     //PCI bus-- which we can only do conditionally.
> +     if(allow_bus_reset && device_supports_bus_reset(dev)) {
> +             dev_dbg(&dev->dev, "Resetting device using an SBR.");
> +             return pci_try_reset_bus(dev->bus);
> +     }
> +
> +     //If we weren't able to reset the device by any of our known-good 
> methods,
> +     //fall back to the linux kernel's reset function. Unfortunately, this 
> considers a
> +     //power management reset to be a valid reset; though this doesn't work 
> for many devices--
> +     //especially GPUs.
> +     dev_err(&dev->dev, "No reset methods available for %s. Falling back to 
> kernel reset.", pci_name(dev));
> +     pci_reset_function(dev);
> +
> +     //Return an error code, indicating that we likely did not reset the 
> device correctly.
> +     return -ENOTTY;
> +}
> +
> +
> +/**
> + * Resets the target (pciback-owned) PCI device. Primarily intended
> + * for use by the toolstack, so it can ensure a consistent PCI device
> + * state on VM startup.
> + *
> + * @param dev The device to be reset.
> + * @return Zero on success, or a negated error code on failure.
> + */
> +static int pcistub_reset_pci_dev(struct pci_dev *dev)
> +{
> +     int rc;
> +
> +     if (!dev)
> +             return -EINVAL;
> +
> +     /*
> +      * Takes the PCI lock. OK to do it as we are never called
> +      * from 'unbind' state and don't deadlock.
> +      */
> +     rc =__pcistub_raw_device_reset(dev);
> +     pci_restore_state(dev);
> +
> +     /* This disables the device. */
> +     xen_pcibk_reset_device(dev);
> +
> +     /* And cleanup up our emulated fields. */
> +     xen_pcibk_config_reset_dev(dev);
> +     return rc;
> +}
> +
> +
> +
>  struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
>                                   struct pci_dev *dev)
>  {
> @@ -279,11 +540,13 @@ void pcistub_put_pci_dev(struct pci_dev
>       * pcistub and xen_pcibk when AER is in processing
>       */
>       down_write(&pcistub_sem);
> -     /* Cleanup our device
> -      * (so it's ready for the next domain)
> -      */
>       device_lock_assert(&dev->dev);
> -     __pci_reset_function_locked(dev);
> +     /*
> +      * Reset is up to the toolstack.
> +      * The toolstack has to call 'reset_device' before
> +      * providing the PCI device to a guest (see pcistub_reset_device).
> +      */
> +     //__pci_reset_function_locked(dev);
>  
>       dev_data = pci_get_drvdata(dev);
>       ret = pci_load_saved_state(dev, dev_data->pci_saved_state);
> @@ -1460,6 +1723,41 @@ static ssize_t restrictive_add(struct de
>  }
>  static DRIVER_ATTR(restrictive, S_IWUSR, NULL, restrictive_add);
>  
> +/**
> + * Handles the "reset_device" sysfs attribute. This is the primary reset 
> interface
> + * utilized by the toolstack.
> + */
> +static ssize_t pcistub_sysfs_reset_device(struct device_driver *drv, const 
> char *buf, size_t count)
> +{
> +     int domain, bus, slot, func, err;
> +     struct pcistub_device *psdev;
> +
> +     //Attempt to convert the user's string to a BDF/slot.
> +     err = str_to_slot(buf, &domain, &bus, &slot, &func);
> +     if (err)
> +             return -ENODEV;
> +
> +     //... and then use that slot to find the pciback device.
> +     psdev = pcistub_device_find(domain, bus, slot, func);
> +
> +     //If we have a device, attempt to reset it using our internal reset 
> path.
> +     if (psdev) {
> +             err = pcistub_reset_pci_dev(psdev->dev);
> +             pcistub_device_put(psdev);
> +
> +             //If we were not able to reset the device, return the relevant 
> error code.
> +             if(err)
> +                     err = -ENODEV;
> +     }
> +     //Otherwise, indicate that there's no such device.
> +     else {
> +             err = -ENODEV;
> +     }
> +
> +     return err ? err : count;
> +
> +}
> +static DRIVER_ATTR(reset_device, S_IWUSR, NULL, pcistub_sysfs_reset_device);
>  
>  static void pcistub_exit(void)
>  {
> @@ -1476,6 +1774,8 @@ static void pcistub_exit(void)
>                          &driver_attr_irq_handlers);
>       driver_remove_file(&xen_pcibk_pci_driver.driver,
>                          &driver_attr_irq_handler_state);
> +     driver_remove_file(&xen_pcibk_pci_driver.driver,
> +                        &driver_attr_reset_device);
>       pci_unregister_driver(&xen_pcibk_pci_driver);
>  }
>  
> @@ -1572,6 +1872,9 @@ static int __init pcistub_init(void)
>       if (!err)
>               err = driver_create_file(&xen_pcibk_pci_driver.driver,
>                                       &driver_attr_irq_handler_state);
> +     if (!err)
> +             err = driver_create_file(&xen_pcibk_pci_driver.driver,
> +                                     &driver_attr_reset_device);
>       if (err)
>               pcistub_exit();
>  

> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> https://lists.xen.org/xen-devel


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.