xen/pcifront: Fix mysterious crashes when NUMA locality information was extracted.
Occasionaly PV guests would crash with: pciback 0000:00:00.1: Xen PCI mapped GSI0 to IRQ16 BUG: unable to handle kernel paging request at 0000000d1a8c0be0 .. snip.. <ffffffff8139ce1b>] find_next_bit+0xb/0x10 [<ffffffff81387f22>] cpumask_next_and+0x22/0x40 [<ffffffff813c1ef8>] pci_device_probe+0xb8/0x120 [<ffffffff81529097>] ? driver_sysfs_add+0x77/0xa0 [<ffffffff815293e4>] driver_probe_device+0x1a4/0x2d0 [<ffffffff813c1ddd>] ? pci_match_device+0xdd/0x110 [<ffffffff81529657>] __device_attach_driver+0xa7/0xb0 [<ffffffff815295b0>] ? __driver_attach+0xa0/0xa0 [<ffffffff81527622>] bus_for_each_drv+0x62/0x90 [<ffffffff8152978d>] __device_attach+0xbd/0x110 [<ffffffff815297fb>] device_attach+0xb/0x10 [<ffffffff813b75ac>] pci_bus_add_device+0x3c/0x70 [<ffffffff813b7618>] pci_bus_add_devices+0x38/0x80 [<ffffffff813dc34e>] pcifront_scan_root+0x13e/0x1a0 [<ffffffff817a0692>] pcifront_backend_changed+0x262/0x60b [<ffffffff814644c6>] ? xenbus_gather+0xd6/0x160 [<ffffffff8120900f>] ? put_object+0x2f/0x50 [<ffffffff81465c1d>] xenbus_otherend_changed+0x9d/0xa0 [<ffffffff814678ee>] backend_changed+0xe/0x10 [<ffffffff81463a28>] xenwatch_thread+0xc8/0x190 [<ffffffff810f22f0>] ? woken_wake_function+0x10/0x10 which was the result of two things: When we call pci_scan_root_bus we would pass in 'sd' (sysdata) pointer which was an 'pcifront_sd' structure. However in the pci_device_add it expects that the 'sd' is 'struct sysdata' and sets the dev->node to what is in sd->node (offset 4): set_dev_node(&dev->dev, pcibus_to_node(bus)); __pcibus_to_node(const struct pci_bus *bus) { const struct pci_sysdata *sd = bus->sysdata; return sd->node; } However our structure was pcifront_sd which had nothing at that offset: struct pcifront_sd { int domain; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ struct pcifront_device * pdev; /* 8 8 */ } That is an hole - filled with garbage as we used kmalloc instead of kzalloc (the second problem). This patch fixes the issue by: 1) Use kzalloc to initialize to a well known state. 2) Put 'struct pci_sysdata' at the start of 'pcifront_sd'. That way access to the 'node' will access the right offset. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: <stable@vger.kernel.org> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
This commit is contained in:
parent
2cfec6a2f9
commit
4d8c8bd6f2
@ -53,7 +53,7 @@ struct pcifront_device {
|
||||
};
|
||||
|
||||
struct pcifront_sd {
|
||||
int domain;
|
||||
struct pci_sysdata sd;
|
||||
struct pcifront_device *pdev;
|
||||
};
|
||||
|
||||
@ -67,7 +67,9 @@ static inline void pcifront_init_sd(struct pcifront_sd *sd,
|
||||
unsigned int domain, unsigned int bus,
|
||||
struct pcifront_device *pdev)
|
||||
{
|
||||
sd->domain = domain;
|
||||
/* Because we do not expose that information via XenBus. */
|
||||
sd->sd.node = first_online_node;
|
||||
sd->sd.domain = domain;
|
||||
sd->pdev = pdev;
|
||||
}
|
||||
|
||||
@ -468,8 +470,8 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
|
||||
dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
|
||||
domain, bus);
|
||||
|
||||
bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
|
||||
sd = kmalloc(sizeof(*sd), GFP_KERNEL);
|
||||
bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
|
||||
sd = kzalloc(sizeof(*sd), GFP_KERNEL);
|
||||
if (!bus_entry || !sd) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
|
Loading…
Reference in New Issue
Block a user