Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361869
b: refs/heads/master
c: 909b3fd
h: refs/heads/master
i:
  361867: b77230b
v: v3
  • Loading branch information
Jan Beulich authored and Konrad Rzeszutek Wilk committed Mar 22, 2013
1 parent 856c6c1 commit c682a19
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 949dd8c14fb2b20b4b815817e66120b22cf531d4
refs/heads/master: 909b3fdb0dd4f3db07b2d75425a00a2adb551383
4 changes: 2 additions & 2 deletions trunk/arch/x86/include/asm/xen/hypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,14 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
return _hypercall3(int, console_io, cmd, count, str);
}

extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
extern int __must_check xen_physdev_op_compat(int, void *);

static inline int
HYPERVISOR_physdev_op(int cmd, void *arg)
{
int rc = _hypercall2(int, physdev_op, cmd, arg);
if (unlikely(rc == -ENOSYS))
rc = HYPERVISOR_physdev_op_compat(cmd, arg);
rc = xen_physdev_op_compat(cmd, arg);
return rc;
}

Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/xen/fallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int xen_event_channel_op_compat(int cmd, void *arg)
}
EXPORT_SYMBOL_GPL(xen_event_channel_op_compat);

int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
int xen_physdev_op_compat(int cmd, void *arg)
{
struct physdev_op op;
int rc;
Expand Down Expand Up @@ -78,3 +78,4 @@ int HYPERVISOR_physdev_op_compat(int cmd, void *arg)

return rc;
}
EXPORT_SYMBOL_GPL(xen_physdev_op_compat);
59 changes: 44 additions & 15 deletions trunk/drivers/xen/xen-pciback/pci_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <xen/events.h>
#include <asm/xen/pci.h>
#include <asm/xen/hypervisor.h>
#include <xen/interface/physdev.h>
#include "pciback.h"
#include "conf_space.h"
#include "conf_space_quirks.h"
Expand Down Expand Up @@ -85,37 +86,52 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
static void pcistub_device_release(struct kref *kref)
{
struct pcistub_device *psdev;
struct pci_dev *dev;
struct xen_pcibk_dev_data *dev_data;

psdev = container_of(kref, struct pcistub_device, kref);
dev_data = pci_get_drvdata(psdev->dev);
dev = psdev->dev;
dev_data = pci_get_drvdata(dev);

dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
dev_dbg(&dev->dev, "pcistub_device_release\n");

xen_unregister_device_domain_owner(psdev->dev);
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(psdev->dev);
if (pci_load_and_free_saved_state(psdev->dev,
&dev_data->pci_saved_state)) {
dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n");
} else
pci_restore_state(psdev->dev);
__pci_reset_function_locked(dev);
if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
dev_dbg(&dev->dev, "Could not reload PCI state\n");
else
pci_restore_state(dev);

if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
struct physdev_pci_device ppdev = {
.seg = pci_domain_nr(dev->bus),
.bus = dev->bus->number,
.devfn = dev->devfn
};
int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix,
&ppdev);

if (err)
dev_warn(&dev->dev, "MSI-X release failed (%d)\n",
err);
}

/* Disable the device */
xen_pcibk_reset_device(psdev->dev);
xen_pcibk_reset_device(dev);

kfree(dev_data);
pci_set_drvdata(psdev->dev, NULL);
pci_set_drvdata(dev, NULL);

/* Clean-up the device */
xen_pcibk_config_free_dyn_fields(psdev->dev);
xen_pcibk_config_free_dev(psdev->dev);
xen_pcibk_config_free_dyn_fields(dev);
xen_pcibk_config_free_dev(dev);

psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
pci_dev_put(psdev->dev);
dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
pci_dev_put(dev);

kfree(psdev);
}
Expand Down Expand Up @@ -355,6 +371,19 @@ static int pcistub_init_device(struct pci_dev *dev)
if (err)
goto config_release;

if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
struct physdev_pci_device ppdev = {
.seg = pci_domain_nr(dev->bus),
.bus = dev->bus->number,
.devfn = dev->devfn
};

err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev);
if (err)
dev_err(&dev->dev, "MSI-X preparation failed (%d)\n",
err);
}

/* We need the device active to save the state. */
dev_dbg(&dev->dev, "save state of device\n");
pci_save_state(dev);
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/xen/interface/physdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ struct physdev_pci_device_add {

#define PHYSDEVOP_pci_device_remove 26
#define PHYSDEVOP_restore_msi_ext 27
/*
* Dom0 should use these two to announce MMIO resources assigned to
* MSI-X capable devices won't (prepare) or may (release) change.
*/
#define PHYSDEVOP_prepare_msix 30
#define PHYSDEVOP_release_msix 31
struct physdev_pci_device {
/* IN */
uint16_t seg;
Expand Down

0 comments on commit c682a19

Please sign in to comment.