Skip to content

Commit

Permalink
powerpc: Fix kexec with dynamic dma windows
Browse files Browse the repository at this point in the history
When we kexec we look for a particular property added by the first
kernel, "linux,direct64-ddr-window-info", per-device where we already
have set up dynamic dma windows. The current code, though, wasn't
initializing the size of this property and thus when we kexec'd, we
would find the property but read uninitialized memory resulting in
garbage ddw values for the kexec'd kernel and panics. Fix this by
setting the size at enable_ddw() time and ensuring that the size of the
found property is valid at dupe_ddw_if_kexec() time.

Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Nishanth Aravamudan authored and Benjamin Herrenschmidt committed May 19, 2011
1 parent 3135540 commit 7673033
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions arch/powerpc/platforms/pseries/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,16 +730,20 @@ static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn)
pcidn = PCI_DN(dn);
direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
if (direct64) {
window = kzalloc(sizeof(*window), GFP_KERNEL);
if (!window) {
if (len < sizeof(struct dynamic_dma_window_prop)) {
remove_ddw(pdn);
} else {
window->device = pdn;
window->prop = direct64;
spin_lock(&direct_window_list_lock);
list_add(&window->list, &direct_window_list);
spin_unlock(&direct_window_list_lock);
dma_addr = direct64->dma_base;
window = kzalloc(sizeof(*window), GFP_KERNEL);
if (!window) {
remove_ddw(pdn);
} else {
window->device = pdn;
window->prop = direct64;
spin_lock(&direct_window_list_lock);
list_add(&window->list, &direct_window_list);
spin_unlock(&direct_window_list_lock);
dma_addr = direct64->dma_base;
}
}
}

Expand Down Expand Up @@ -833,7 +837,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
struct device_node *dn;
const u32 *uninitialized_var(ddr_avail);
struct direct_window *window;
struct property *uninitialized_var(win64);
struct property *win64;
struct dynamic_dma_window_prop *ddwprop;

mutex_lock(&direct_window_init_mutex);
Expand Down Expand Up @@ -907,6 +911,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
}
win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL);
win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL);
win64->length = sizeof(*ddwprop);
if (!win64->name || !win64->value) {
dev_info(&dev->dev,
"couldn't allocate property name and value\n");
Expand Down

0 comments on commit 7673033

Please sign in to comment.