[PATCH] pci: Repair pci_save/restore_state so we can restore one save many times.

Because we do not reserve space for the pci-x and pci-e state in struct
pci dev we need to dynamically allocate it. However because we need
to support restore being called multiple times after a single save
it is never safe to free the buffers we have allocated to hold the
state.

So this patch modifies the save routines to first check to see
if we have already allocated a state buffer before allocating
a new one. Then the restore routines are modified to not free
the state after restoring it. Simple and it fixes some subtle
error path handling bugs, that are hard to test for.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Eric W. Biederman and committed by Linus Torvalds 9f35575d 392ee1e6

+6 -11
+6 -6
drivers/pci/pci.c
··· 551 if (pos <= 0) 552 return 0; 553 554 - save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); 555 if (!save_state) { 556 dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); 557 return -ENOMEM; ··· 584 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); 585 pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); 586 pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); 587 - pci_remove_saved_cap(save_state); 588 - kfree(save_state); 589 } 590 591 ··· 597 if (pos <= 0) 598 return 0; 599 600 - save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); 601 if (!save_state) { 602 dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); 603 return -ENOMEM; ··· 624 cap = (u16 *)&save_state->data[0]; 625 626 pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); 627 - pci_remove_saved_cap(save_state); 628 - kfree(save_state); 629 } 630 631
··· 551 if (pos <= 0) 552 return 0; 553 554 + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); 555 + if (!save_state) 556 + save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); 557 if (!save_state) { 558 dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); 559 return -ENOMEM; ··· 582 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); 583 pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); 584 pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); 585 } 586 587 ··· 597 if (pos <= 0) 598 return 0; 599 600 + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); 601 + if (!save_state) 602 + save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); 603 if (!save_state) { 604 dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); 605 return -ENOMEM; ··· 622 cap = (u16 *)&save_state->data[0]; 623 624 pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); 625 } 626 627
-5
include/linux/pci.h
··· 209 hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); 210 } 211 212 - static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) 213 - { 214 - hlist_del(&cap->next); 215 - } 216 - 217 /* 218 * For PCI devices, the region numbers are assigned this way: 219 *
··· 209 hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); 210 } 211 212 /* 213 * For PCI devices, the region numbers are assigned this way: 214 *