Re: [PATCH] Fix warning

2012-04-04 Thread Tadeusz Struk
Hi Bjorn,
Did you have chance to look at this one?
Regards,
Tadeusz

On 01/03/12 17:18, tadeusz.st...@intel.com wrote:
> From: Tadeusz Struk 
> Date: Mon, 14 Feb 2011 14:38:18 +
> Subject: [PATCH] Fixed warning
> 
> This patch fixes the following warning.
> # virsh start fedora16-64
> kernel: [  133.324565] pci-stub :02:01.1: claimed by stub
> kernel: [  134.163769] pci-stub :02:01.1: enabling device ( -> 0002)
> kernel: [  164.282679] [ cut here ]
> kernel: [  164.282685] WARNING: at drivers/pci/search.c:46 
> pci_find_upstream_pcie_bridge+0x87/0x9f()
> kernel: [  164.282687] Hardware name: SandyBridge Platform
> kernel: [  164.282689] Modules linked in: sha512_generic sha256_generic 
> icp_qa_al(O) nfs fscache auth_rpcgss nfs_acl mga drm ip6table_filter 
> ip6_tables ebtable_nat ebtables lockd ipt_MASQUERADE iptable_nat nf_nat 
> nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack xt_CHECKSUM 
> iptable_mangle tun bridge stp llc sunrpc btrfs zlib_deflate libcrc32c 
> virtio_net kvm_intel kvm uinput matroxfb_base matroxfb_DAC1064 matroxfb_accel 
> matroxfb_Ti3026 matroxfb_g450 g450_pll matroxfb_misc e1000e iTCO_wdt 
> iTCO_vendor_support igb microcode i2c_i801 shpchp serio_raw i2c_core pcspkr 
> dca [last unloaded: scsi_wait_scan]
> kernel: [  164.282724] Pid: 1233, comm: qemu-kvm Tainted: G   O 3.2.5 
> #10
> kernel: [  164.282726] Call Trace:
> kernel: [  164.282732]  [] warn_slowpath_common+0x83/0x9b
> kernel: [  164.282735]  [] warn_slowpath_null+0x1a/0x1c
> kernel: [  164.282737]  [] 
> pci_find_upstream_pcie_bridge+0x87/0x9f
> kernel: [  164.282741]  [] domain_context_mapping+0x50/0xe6
> kernel: [  164.282744]  [] domain_add_dev_info+0x44/0xe3
> kernel: [  164.282747]  [] 
> intel_iommu_attach_device+0x14f/0x15c
> kernel: [  164.282750]  [] iommu_attach_device+0x1c/0x1e
> kernel: [  164.282764]  [] kvm_assign_device+0x4a/0x114 
> [kvm]
> kernel: [  164.282773]  [] 
> kvm_vm_ioctl_assigned_device+0x434/0xb25 [kvm]
> kernel: [  164.282777]  [] ? __do_fault+0x351/0x38b
> kernel: [  164.282781]  [] ? arch_local_irq_save+0x15/0x1b
> kernel: [  164.282784]  [] ? 
> _raw_spin_unlock_irqrestore+0x17/0x19
> kernel: [  164.282787]  [] ? pci_conf1_read+0xe1/0xee
> kernel: [  164.282794]  [] kvm_vm_ioctl+0x377/0x3ac [kvm]
> kernel: [  164.282797]  [] ? pci_read_config+0xa2/0x1bd
> kernel: [  164.282801]  [] ? virt_to_head_page+0xe/0x31
> kernel: [  164.282804]  [] do_vfs_ioctl+0x45d/0x49e
> kernel: [  164.282808]  [] ? fsnotify_access+0x5f/0x67
> kernel: [  164.282811]  [] sys_ioctl+0x56/0x7b
> kernel: [  164.282814]  [] system_call_fastpath+0x16/0x1b
> kernel: [  164.282816] ---[ end trace 6a834ec5ac21cba8 ]---
> 
> Signed-off-by: Tadeusz Struk 
> 
> ---
>  drivers/pci/search.c |7 +--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/search.c b/drivers/pci/search.c
> index 9d75dc8..7847c6b 100644
> --- a/drivers/pci/search.c
> +++ b/drivers/pci/search.c
> @@ -26,6 +26,7 @@ struct pci_dev *
>  pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
>  {
>   struct pci_dev *tmp = NULL;
> + struct pci_dev *vf = pdev;
>  
>   if (pci_is_pcie(pdev))
>   return NULL;
> @@ -40,8 +41,10 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
>   }
>   /* PCI device should connect to a PCIe bridge */
>   if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
> - /* Busted hardware? */
> - WARN_ON_ONCE(1);
> + if (!vf->is_virtfn) {
> + /* Busted hardware? */
> + WARN_ON_ONCE(1);
> + }
>   return NULL;
>   }
>   return pdev;

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] PCI: Device specific reset function

2012-03-14 Thread Tadeusz Struk
On 13/03/12 02:42, Alex Williamson wrote:
> On Mon, 2012-03-12 at 16:55 +0000, Tadeusz Struk wrote:
>> I have a use case where I need to cleanup resource allocated for Virtual
>> Functions after a guest OS that used it crashed. This cleanup needs to
>> be done before the VF is being FLRed. The only possible way to do this
>> seems to be by using pci_dev_specific_reset() function.
>> This patch adds specific reset function to the pci_driver struct.
>>
>> Signed-off-by: Tadeusz Struk 
>> ---
>>  drivers/pci/quirks.c |4 
>>  include/linux/pci.h  |1 +
>>  2 files changed, 5 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>> index 6476547..13d224b 100644
>> --- a/drivers/pci/quirks.c
>> +++ b/drivers/pci/quirks.c
>> @@ -3081,8 +3081,12 @@ static const struct pci_dev_reset_methods 
>> pci_dev_reset_methods[] = {
>>  
>>  int pci_dev_specific_reset(struct pci_dev *dev, int probe)
>>  {
>> +struct pci_driver *drv = dev->driver;
>>  const struct pci_dev_reset_methods *i;
>>  
>> +if (drv && drv->reset)
>> +return drv->reset(dev, probe);
>> +
> 
> Isn't this exactly what the below code is for (pci_dev_reset_methods)?
> In the case of KVM device assignment, the device should be reset via
> this path if the guest crashes, but it may or may not be attached to
> pci-stub at the time.  I assume you're not adding a reset handler to
> pci-stub, so we'll pass through here and use FLR, violating the premise
> of the patch.  Thanks,
> 
> Alex

Hi,
The reset handler supposed to be in the "real" driver not in the pci-stub.
You are right, at this stage the VF can still be assigned to the pci-stub, 
which makes it useless in my case.
I think the only option for me will be to go with the v2 of the patch.
I'll do a bit more testing to make sure this is the case and resend the v2.
Thanks,
Tadeusz


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] PCI: Device specific reset function

2012-03-12 Thread Tadeusz Struk
I have a use case where I need to cleanup resource allocated for Virtual
Functions after a guest OS that used it crashed. This cleanup needs to
be done before the VF is being FLRed. The only possible way to do this
seems to be by using pci_dev_specific_reset() function.
This patch adds specific reset function to the pci_driver struct.

Signed-off-by: Tadeusz Struk 
---
 drivers/pci/quirks.c |4 
 include/linux/pci.h  |1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6476547..13d224b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3081,8 +3081,12 @@ static const struct pci_dev_reset_methods 
pci_dev_reset_methods[] = {
 
 int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
+   struct pci_driver *drv = dev->driver;
const struct pci_dev_reset_methods *i;
 
+   if (drv && drv->reset)
+   return drv->reset(dev, probe);
+
for (i = pci_dev_reset_methods; i->reset; i++) {
if ((i->vendor == dev->vendor ||
 i->vendor == (u16)PCI_ANY_ID) &&
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a16b1df..2ccd838 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -560,6 +560,7 @@ struct pci_driver {
int  (*resume_early) (struct pci_dev *dev);
int  (*resume) (struct pci_dev *dev);   /* Device woken 
up */
void (*shutdown) (struct pci_dev *dev);
+   int  (*reset) (struct pci_dev *dev, int probe);
struct pci_error_handlers *err_handler;
struct device_driverdriver;
struct pci_dynids dynids;
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/1] PCI: Device specific reset function

2012-03-05 Thread Tadeusz Struk
Hi,
I have a use case where I need to cleanup resource allocated for Virtual
Functions after a guest OS that used it crashed. This cleanup needs to
be done before the VF is being FLRed. The only possible way to do this
seems to be by using pci_dev_specific_reset() function. Unfortunately
this function only works for devices defined in a static table in the
drivers/pci/quirks.c file. This patch changes it so that specific reset
handler is part of pci_driver struct.


 drivers/pci/pci.h|1 +
 drivers/pci/quirks.c |   33 +++--
 include/linux/pci.h  |1 +
 3 files changed, 29 insertions(+), 6 deletions(-)

--
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). Any review or distribution by others is 
strictly prohibited. If you are not the intended recipient, please contact the 
sender and delete all copies.


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1 v3] PCI: Device specific reset function

2012-03-05 Thread Tadeusz Struk

---
 drivers/pci/pci.h|1 +
 drivers/pci/quirks.c |   33 +++--
 include/linux/pci.h  |1 +
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1009a5e..4d10479 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -315,6 +315,7 @@ struct pci_dev_reset_methods {
u16 vendor;
u16 device;
int (*reset)(struct pci_dev *dev, int probe);
+   struct list_head list;
 };
 
 #ifdef CONFIG_PCI_QUIRKS
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6476547..f423d2f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3070,26 +3070,47 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev 
*dev, int probe)
 }
 
 #define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
-
-static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
+static struct pci_dev_reset_methods pci_dev_reset_methods[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
-reset_intel_82599_sfp_virtfn },
+   reset_intel_82599_sfp_virtfn },
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
reset_intel_generic_dev },
-   { 0 }
 };
 
+static LIST_HEAD(reset_list);
+
+void pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method)
+{
+   INIT_LIST_HEAD(&reset_method->list);
+   list_add(&reset_method->list, &reset_list);
+}
+
+static int __init pci_dev_specific_reset_init(void)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(pci_dev_reset_methods); i++) {
+   pci_dev_specific_reset_add(&pci_dev_reset_methods[i]);
+   }
+   return 0;
+}
+
+late_initcall(pci_dev_specific_reset_init);
+
 int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
const struct pci_dev_reset_methods *i;
+   struct pci_driver *drv = dev->driver;
+
+   if (drv && drv->reset)
+   return drv->reset(dev, probe);
 
-   for (i = pci_dev_reset_methods; i->reset; i++) {
+   list_for_each_entry(i, &reset_list, list) {
if ((i->vendor == dev->vendor ||
 i->vendor == (u16)PCI_ANY_ID) &&
(i->device == dev->device ||
 i->device == (u16)PCI_ANY_ID))
return i->reset(dev, probe);
}
-
return -ENOTTY;
 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a16b1df..a3a0bc5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -560,6 +560,7 @@ struct pci_driver {
int  (*resume_early) (struct pci_dev *dev);
int  (*resume) (struct pci_dev *dev);   /* Device woken 
up */
void (*shutdown) (struct pci_dev *dev);
+   int  (*reset) (struct pci_dev *dev, int probe); /* Device specific 
reset */
struct pci_error_handlers *err_handler;
struct device_driverdriver;
struct pci_dynids dynids;
-- 
1.7.7.6

--
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). Any review or distribution by others is 
strictly prohibited. If you are not the intended recipient, please contact the 
sender and delete all copies.


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] Dynamically add and remove device specific reset functions

2012-03-02 Thread Tadeusz Struk
On 02/03/12 16:29, Bjorn Helgaas wrote:
> Where do you plan to add calls to pci_dev_specific_reset_add()?  In
> drivers?

Yes, I'm working on a driver for a device with SRIOV capability.
I'll call it from there.

> Did you consider adding a "reset" function pointer to struct
> pci_driver?  That might be more natural -- the reset function is right
> with all the other code that knows about the device, and there's no
> issue with looking up the correct reset function.
> With this patch, we sort of have two different ways to map
> vendor/device IDs to code: the usual pci_register_driver() approach,
> and this one using reset_list.  If pci_driver had a "reset" pointer,
> that would be used most of the time.  You might still need the
> reset_list for generic things, e.g., the reset_intel_generic_dev()
> function, but it would be a fallback.  It might look something like:
> 
> struct pci_driver *drv = dev->driver;
> 
> if (drv && drv->reset) {
> drv->reset(dev);
> return;
> }
> 
> list_for_each_entry(i, &reset_list, list) {
> ...
> 

No, I didn't think about it.
This is good idea, but for me the pci_dev_specific_reset() works fine.

> In that case, you might not even need the ability to dynamically add
> things to the list, since the only things to add would be "generic"
> things that would be more static.
> 
> Perhaps this approach was previously discussed and discarded; if so, I
> missed it.
> 
> Bjorn

Do you want me to send another patch that fixes these minor issues you pointed 
out?
Thanks for you comments.
Tadeusz

--
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). Any review or distribution by others is 
strictly prohibited. If you are not the intended recipient, please contact the 
sender and delete all copies.


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] Dynamically add and remove device specific reset functions

2012-03-02 Thread tadeusz . struk
Hi,
Reworked according to comments.
I have a use case where I need to cleanup resource allocated for Virtual
Functions after a guest OS that used it crashed. This cleanup needs to
be done before the VF is being FLRed. The only possible way to do this
seems to be by using pci_dev_specific_reset() function. Unfortunately
this function only works for devices defined in a static table in the
drivers/pci/quirks.c file. This patch changes it so that specific reset
functions can be added and deleted dynamically.

Signed-off-by: Tadeusz Struk 

---
 drivers/pci/pci.h|   14 +++
 drivers/pci/quirks.c |   61 +
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1009a5e..3e95df6 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -312,6 +312,7 @@ static inline resource_size_t pci_resource_alignment(struct 
pci_dev *dev,
 extern void pci_enable_acs(struct pci_dev *dev);
 
 struct pci_dev_reset_methods {
+   struct list_head list;
u16 vendor;
u16 device;
int (*reset)(struct pci_dev *dev, int probe);
@@ -319,11 +320,24 @@ struct pci_dev_reset_methods {
 
 #ifdef CONFIG_PCI_QUIRKS
 extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int pci_dev_specific_reset_add(struct pci_dev_reset_methods
+   *reset_method);
+extern int pci_dev_specific_reset_remove(struct pci_dev_reset_methods
+   *reset_method);
 #else
 static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
return -ENOTTY;
 }
+int pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method)
+{
+   return 0;
+}
+int
+pci_dev_specific_reset_remove(struct pci_dev_reset_methods *reset_method)
+{
+   return 0;
+}
 #endif
 
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6476547..a0152fd 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3070,26 +3070,67 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev 
*dev, int probe)
 }
 
 #define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
-
-static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
-   { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
-reset_intel_82599_sfp_virtfn },
-   { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+static struct pci_dev_reset_methods pci_dev_reset_methods[] = {
+   { {NULL, NULL}, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
+   reset_intel_82599_sfp_virtfn },
+   { {NULL, NULL}, PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
reset_intel_generic_dev },
-   { 0 }
 };
 
+static DEFINE_SPINLOCK(reset_list_lock);
+static LIST_HEAD(reset_list);
+
+static int __init pci_dev_specific_reset_init(void)
+{
+   int i;
+   for (i = 0; i < ARRAY_SIZE(pci_dev_reset_methods); i++) {
+   pci_dev_specific_reset_add(&pci_dev_reset_methods[i]);
+   }
+   return 0;
+}
+
+late_initcall(pci_dev_specific_reset_init);
+
+int pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method)
+{
+   WARN_ON(!reset_method->reset);
+   INIT_LIST_HEAD(&reset_method->list);
+   spin_lock(&reset_list_lock);
+   list_add(&reset_method->list, &reset_list);
+   spin_unlock(&reset_list_lock);
+   return 0;
+}
+EXPORT_SYMBOL(pci_dev_specific_reset_add);
+
+int pci_dev_specific_reset_remove(struct pci_dev_reset_methods *reset_method)
+{
+   spin_lock(&reset_list_lock);
+   list_del(&reset_method->list);
+   spin_unlock(&reset_list_lock);
+   return 0;
+}
+EXPORT_SYMBOL(pci_dev_specific_reset_remove);
+
 int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
const struct pci_dev_reset_methods *i;
+   spin_lock(&reset_list_lock);
+   list_for_each_entry(i, &reset_list, list) {
+   if (i->vendor == dev->vendor &&
+   i->device == dev->device) {
+   spin_unlock(&reset_list_lock);
+   return i->reset(dev, probe);
+   }
+   }
 
-   for (i = pci_dev_reset_methods; i->reset; i++) {
+   list_for_each_entry(i, &reset_list, list) {
if ((i->vendor == dev->vendor ||
 i->vendor == (u16)PCI_ANY_ID) &&
-   (i->device == dev->device ||
-i->device == (u16)PCI_ANY_ID))
+i->device == (u16)PCI_ANY_ID) {
+   spin_unlock(&reset_list_lock);
return i->reset(dev, probe);
+   }
}
-
+   spin_unlock(&reset_list_lock);
return -ENOTTY;
 }
-- 
1.7.7.6

--
Intel Shannon Limited
Registered in Ireland
Registe

[PATCH] Fix warning

2012-03-01 Thread tadeusz . struk
>From 268c5427305d59c1f6f6c1ce8047f6e32a7edcac Mon Sep 17 00:00:00 2001
From: Tadeusz Struk 
Date: Mon, 14 Feb 2011 14:38:18 +
Subject: [PATCH] Fixed warning

This patch fixes the following warning.
# virsh start fedora16-64
kernel: [  133.324565] pci-stub :02:01.1: claimed by stub
kernel: [  134.163769] pci-stub :02:01.1: enabling device ( -> 0002)
kernel: [  164.282679] [ cut here ]
kernel: [  164.282685] WARNING: at drivers/pci/search.c:46 
pci_find_upstream_pcie_bridge+0x87/0x9f()
kernel: [  164.282687] Hardware name: SandyBridge Platform
kernel: [  164.282689] Modules linked in: sha512_generic sha256_generic 
icp_qa_al(O) nfs fscache auth_rpcgss nfs_acl mga drm ip6table_filter ip6_tables 
ebtable_nat ebtables lockd ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 
nf_defrag_ipv4 xt_state nf_conntrack xt_CHECKSUM iptable_mangle tun bridge stp 
llc sunrpc btrfs zlib_deflate libcrc32c virtio_net kvm_intel kvm uinput 
matroxfb_base matroxfb_DAC1064 matroxfb_accel matroxfb_Ti3026 matroxfb_g450 
g450_pll matroxfb_misc e1000e iTCO_wdt iTCO_vendor_support igb microcode 
i2c_i801 shpchp serio_raw i2c_core pcspkr dca [last unloaded: scsi_wait_scan]
kernel: [  164.282724] Pid: 1233, comm: qemu-kvm Tainted: G   O 3.2.5 
#10
kernel: [  164.282726] Call Trace:
kernel: [  164.282732]  [] warn_slowpath_common+0x83/0x9b
kernel: [  164.282735]  [] warn_slowpath_null+0x1a/0x1c
kernel: [  164.282737]  [] 
pci_find_upstream_pcie_bridge+0x87/0x9f
kernel: [  164.282741]  [] domain_context_mapping+0x50/0xe6
kernel: [  164.282744]  [] domain_add_dev_info+0x44/0xe3
kernel: [  164.282747]  [] 
intel_iommu_attach_device+0x14f/0x15c
kernel: [  164.282750]  [] iommu_attach_device+0x1c/0x1e
kernel: [  164.282764]  [] kvm_assign_device+0x4a/0x114 [kvm]
kernel: [  164.282773]  [] 
kvm_vm_ioctl_assigned_device+0x434/0xb25 [kvm]
kernel: [  164.282777]  [] ? __do_fault+0x351/0x38b
kernel: [  164.282781]  [] ? arch_local_irq_save+0x15/0x1b
kernel: [  164.282784]  [] ? 
_raw_spin_unlock_irqrestore+0x17/0x19
kernel: [  164.282787]  [] ? pci_conf1_read+0xe1/0xee
kernel: [  164.282794]  [] kvm_vm_ioctl+0x377/0x3ac [kvm]
kernel: [  164.282797]  [] ? pci_read_config+0xa2/0x1bd
kernel: [  164.282801]  [] ? virt_to_head_page+0xe/0x31
kernel: [  164.282804]  [] do_vfs_ioctl+0x45d/0x49e
kernel: [  164.282808]  [] ? fsnotify_access+0x5f/0x67
kernel: [  164.282811]  [] sys_ioctl+0x56/0x7b
kernel: [  164.282814]  [] system_call_fastpath+0x16/0x1b
kernel: [  164.282816] ---[ end trace 6a834ec5ac21cba8 ]---

Signed-off-by: Tadeusz Struk 

---
 drivers/pci/search.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 9d75dc8..7847c6b 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -26,6 +26,7 @@ struct pci_dev *
 pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
 {
struct pci_dev *tmp = NULL;
+   struct pci_dev *vf = pdev;
 
if (pci_is_pcie(pdev))
return NULL;
@@ -40,8 +41,10 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
}
/* PCI device should connect to a PCIe bridge */
if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
-   /* Busted hardware? */
-   WARN_ON_ONCE(1);
+   if (!vf->is_virtfn) {
+   /* Busted hardware? */
+   WARN_ON_ONCE(1);
+   }
return NULL;
}
return pdev;
-- 
1.7.7.6

--
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). Any review or distribution by others is 
strictly prohibited. If you are not the intended recipient, please contact the 
sender and delete all copies.


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Added functionality that allows dynamically add and remove device specific reset functions

2012-03-01 Thread tadeusz . struk
>From b4cf24d5987475862de799c78773f13f25ed2af8 Mon Sep 17 00:00:00 2001
From: Tadeusz Struk 
Date: Tue, 17 Jan 2012 16:45:46 +
Subject: [PATCH] Added functionality that allows dynamically add and remove
 device specific reset functions

I have a use case where I need to cleanup resource allocated for Virtual
Functions after a guest OS that used it crashed. This cleanup needs to
be done before the VF is being FLRed. The only possible way to do this
seems to be by using pci_dev_specific_reset() function. Unfortunately
this function only works for devices defined in a static table in the
drivers/pci/quirks.c file. This patch changes it so that specific reset
functions can be added and deleted dynamically.

Signed-off-by: Tadeusz Struk 

---
 drivers/pci/pci.h|   19 ++-
 drivers/pci/quirks.c |   63 ++
 2 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1009a5e..10929d8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -312,18 +312,35 @@ static inline resource_size_t 
pci_resource_alignment(struct pci_dev *dev,
 extern void pci_enable_acs(struct pci_dev *dev);
 
 struct pci_dev_reset_methods {
+   struct list_head list;
u16 vendor;
u16 device;
int (*reset)(struct pci_dev *dev, int probe);
 };
 
 #ifdef CONFIG_PCI_QUIRKS
-extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int
+pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int
+pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method);
+extern int
+pci_dev_specific_reset_remove(const struct pci_dev_reset_methods 
*reset_method);
+
 #else
 static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
return -ENOTTY;
 }
+int
+pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method)
+{
+   return 0;
+}
+int
+pci_dev_specific_reset_remove(const struct pci_dev_reset_methods *reset_method)
+{
+   return 0;
+}
 #endif
 
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6476547..963e527 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3070,26 +3070,69 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev 
*dev, int probe)
 }
 
 #define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
+static struct pci_dev_reset_methods intel_82599_sfp_vf_reset = {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_DEVICE_ID_INTEL_82599_SFP_VF,
+   .reset = reset_intel_82599_sfp_virtfn,
+   .list = LIST_HEAD_INIT(intel_82599_sfp_vf_reset.list)
+} ;
 
-static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
-   { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
-reset_intel_82599_sfp_virtfn },
-   { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
-   reset_intel_generic_dev },
-   { 0 }
-};
+static struct pci_dev_reset_methods intel_generic_reset = {
+   .vendor = PCI_VENDOR_ID_INTEL,
+   .device = PCI_ANY_ID,
+   .reset = reset_intel_generic_dev,
+   .list = LIST_HEAD_INIT(intel_generic_reset.list)
+} ;
+
+static DEFINE_SPINLOCK(reset_list_lock);
+static LIST_HEAD(reset_list);
+
+
+static int __init pci_dev_specific_reset_init(void)
+{
+   pci_dev_specific_reset_add(&intel_82599_sfp_vf_reset);
+   pci_dev_specific_reset_add(&intel_generic_reset);
+   return 0;
+}
+
+late_initcall(pci_dev_specific_reset_init);
+
+int
+pci_dev_specific_reset_add(const struct pci_dev_reset_methods *reset_method)
+{
+   if (reset_method && reset_method->reset) {
+   spin_lock(&reset_list_lock);
+   list_add((struct list_head *)&reset_method->list,
+&reset_list);
+   spin_unlock(&reset_list_lock);
+   return 0;
+   }
+   return -EINVAL;
+}
+EXPORT_SYMBOL(pci_dev_specific_reset_add);
+
+int
+pci_dev_specific_reset_remove(const struct pci_dev_reset_methods *reset_method)
+{
+   if (reset_method) {
+   spin_lock(&reset_list_lock);
+   list_del((struct list_head *)(&reset_method->list));
+   spin_unlock(&reset_list_lock);
+   return 0;
+   }
+   return -EINVAL;
+}
+EXPORT_SYMBOL(pci_dev_specific_reset_remove);
 
 int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 {
const struct pci_dev_reset_methods *i;
-
-   for (i = pci_dev_reset_methods; i->reset; i++) {
+   list_for_each_entry(i, &reset_list, list) {
if ((i->vendor == dev->vendor ||
 i->vendor == (u16)PCI_ANY_ID) &&
(i->device == dev->device ||
 i->device == (u16)PCI_ANY_ID))
return i->reset(dev, probe);
}
-
return -ENOTTY;
 }
-- 
1.7.7.6