aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-16 00:31:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-16 00:31:19 -0400
commitc1c2ad82c772966d3cdb9a4852329fa2cf71853a (patch)
tree1296ea11754303d3a2cdf5c157984e8aae509e9f
parent99a2c789ddeb703cf7b0a3d889ab1a25cf4cbbaf (diff)
parent190bd6e98afc512fb16d4a471acd488e36141637 (diff)
Merge tag 'edac_for_4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
Pull EDAC updates from Borislav Petkov: - Add support for systems with PCI segmented buses to sb_edac, by Masayoshi Mizuma - The usual pile of fixes and cleanups * tag 'edac_for_4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: EDAC, sb_edac: Add support for systems with segmented PCI buses EDAC, thunderx: Remove VLA usage EDAC, i7core: Fix memleaks and use-after-free on probe and remove EDAC: Fix memleak in module init error path EDAC, altera: Fix an error handling path in altr_s10_sdram_probe()
-rw-r--r--drivers/edac/altera_edac.c3
-rw-r--r--drivers/edac/edac_mc_sysfs.c6
-rw-r--r--drivers/edac/i7core_edac.c22
-rw-r--r--drivers/edac/sb_edac.c17
-rw-r--r--drivers/edac/thunderx_edac.c14
5 files changed, 41 insertions, 21 deletions
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index d0d5c4dbe097..5762c3c383f2 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -730,7 +730,8 @@ static int altr_s10_sdram_probe(struct platform_device *pdev)
730 S10_DDR0_IRQ_MASK)) { 730 S10_DDR0_IRQ_MASK)) {
731 edac_printk(KERN_ERR, EDAC_MC, 731 edac_printk(KERN_ERR, EDAC_MC,
732 "Error clearing SDRAM ECC count\n"); 732 "Error clearing SDRAM ECC count\n");
733 return -ENODEV; 733 ret = -ENODEV;
734 goto err2;
734 } 735 }
735 736
736 if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset, 737 if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset,
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 7481955160a4..20374b8248f0 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -1075,14 +1075,14 @@ int __init edac_mc_sysfs_init(void)
1075 1075
1076 err = device_add(mci_pdev); 1076 err = device_add(mci_pdev);
1077 if (err < 0) 1077 if (err < 0)
1078 goto out_dev_free; 1078 goto out_put_device;
1079 1079
1080 edac_dbg(0, "device %s created\n", dev_name(mci_pdev)); 1080 edac_dbg(0, "device %s created\n", dev_name(mci_pdev));
1081 1081
1082 return 0; 1082 return 0;
1083 1083
1084 out_dev_free: 1084 out_put_device:
1085 kfree(mci_pdev); 1085 put_device(mci_pdev);
1086 out: 1086 out:
1087 return err; 1087 return err;
1088} 1088}
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 8ed4dd9c571b..8e120bf60624 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1177,15 +1177,14 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1177 1177
1178 rc = device_add(pvt->addrmatch_dev); 1178 rc = device_add(pvt->addrmatch_dev);
1179 if (rc < 0) 1179 if (rc < 0)
1180 return rc; 1180 goto err_put_addrmatch;
1181 1181
1182 if (!pvt->is_registered) { 1182 if (!pvt->is_registered) {
1183 pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev), 1183 pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
1184 GFP_KERNEL); 1184 GFP_KERNEL);
1185 if (!pvt->chancounts_dev) { 1185 if (!pvt->chancounts_dev) {
1186 put_device(pvt->addrmatch_dev); 1186 rc = -ENOMEM;
1187 device_del(pvt->addrmatch_dev); 1187 goto err_del_addrmatch;
1188 return -ENOMEM;
1189 } 1188 }
1190 1189
1191 pvt->chancounts_dev->type = &all_channel_counts_type; 1190 pvt->chancounts_dev->type = &all_channel_counts_type;
@@ -1199,9 +1198,18 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1199 1198
1200 rc = device_add(pvt->chancounts_dev); 1199 rc = device_add(pvt->chancounts_dev);
1201 if (rc < 0) 1200 if (rc < 0)
1202 return rc; 1201 goto err_put_chancounts;
1203 } 1202 }
1204 return 0; 1203 return 0;
1204
1205err_put_chancounts:
1206 put_device(pvt->chancounts_dev);
1207err_del_addrmatch:
1208 device_del(pvt->addrmatch_dev);
1209err_put_addrmatch:
1210 put_device(pvt->addrmatch_dev);
1211
1212 return rc;
1205} 1213}
1206 1214
1207static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci) 1215static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
@@ -1211,11 +1219,11 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
1211 edac_dbg(1, "\n"); 1219 edac_dbg(1, "\n");
1212 1220
1213 if (!pvt->is_registered) { 1221 if (!pvt->is_registered) {
1214 put_device(pvt->chancounts_dev);
1215 device_del(pvt->chancounts_dev); 1222 device_del(pvt->chancounts_dev);
1223 put_device(pvt->chancounts_dev);
1216 } 1224 }
1217 put_device(pvt->addrmatch_dev);
1218 device_del(pvt->addrmatch_dev); 1225 device_del(pvt->addrmatch_dev);
1226 put_device(pvt->addrmatch_dev);
1219} 1227}
1220 1228
1221/**************************************************************************** 1229/****************************************************************************
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 4a89c8093307..07726fb00321 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -352,6 +352,7 @@ struct pci_id_table {
352 352
353struct sbridge_dev { 353struct sbridge_dev {
354 struct list_head list; 354 struct list_head list;
355 int seg;
355 u8 bus, mc; 356 u8 bus, mc;
356 u8 node_id, source_id; 357 u8 node_id, source_id;
357 struct pci_dev **pdev; 358 struct pci_dev **pdev;
@@ -729,7 +730,8 @@ static inline int numcol(u32 mtr)
729 return 1 << cols; 730 return 1 << cols;
730} 731}
731 732
732static struct sbridge_dev *get_sbridge_dev(u8 bus, enum domain dom, int multi_bus, 733static struct sbridge_dev *get_sbridge_dev(int seg, u8 bus, enum domain dom,
734 int multi_bus,
733 struct sbridge_dev *prev) 735 struct sbridge_dev *prev)
734{ 736{
735 struct sbridge_dev *sbridge_dev; 737 struct sbridge_dev *sbridge_dev;
@@ -747,14 +749,15 @@ static struct sbridge_dev *get_sbridge_dev(u8 bus, enum domain dom, int multi_bu
747 : sbridge_edac_list.next, struct sbridge_dev, list); 749 : sbridge_edac_list.next, struct sbridge_dev, list);
748 750
749 list_for_each_entry_from(sbridge_dev, &sbridge_edac_list, list) { 751 list_for_each_entry_from(sbridge_dev, &sbridge_edac_list, list) {
750 if (sbridge_dev->bus == bus && (dom == SOCK || dom == sbridge_dev->dom)) 752 if ((sbridge_dev->seg == seg) && (sbridge_dev->bus == bus) &&
753 (dom == SOCK || dom == sbridge_dev->dom))
751 return sbridge_dev; 754 return sbridge_dev;
752 } 755 }
753 756
754 return NULL; 757 return NULL;
755} 758}
756 759
757static struct sbridge_dev *alloc_sbridge_dev(u8 bus, enum domain dom, 760static struct sbridge_dev *alloc_sbridge_dev(int seg, u8 bus, enum domain dom,
758 const struct pci_id_table *table) 761 const struct pci_id_table *table)
759{ 762{
760 struct sbridge_dev *sbridge_dev; 763 struct sbridge_dev *sbridge_dev;
@@ -771,6 +774,7 @@ static struct sbridge_dev *alloc_sbridge_dev(u8 bus, enum domain dom,
771 return NULL; 774 return NULL;
772 } 775 }
773 776
777 sbridge_dev->seg = seg;
774 sbridge_dev->bus = bus; 778 sbridge_dev->bus = bus;
775 sbridge_dev->dom = dom; 779 sbridge_dev->dom = dom;
776 sbridge_dev->n_devs = table->n_devs_per_imc; 780 sbridge_dev->n_devs = table->n_devs_per_imc;
@@ -2246,6 +2250,7 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
2246 struct sbridge_dev *sbridge_dev = NULL; 2250 struct sbridge_dev *sbridge_dev = NULL;
2247 const struct pci_id_descr *dev_descr = &table->descr[devno]; 2251 const struct pci_id_descr *dev_descr = &table->descr[devno];
2248 struct pci_dev *pdev = NULL; 2252 struct pci_dev *pdev = NULL;
2253 int seg = 0;
2249 u8 bus = 0; 2254 u8 bus = 0;
2250 int i = 0; 2255 int i = 0;
2251 2256
@@ -2276,10 +2281,12 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
2276 /* End of list, leave */ 2281 /* End of list, leave */
2277 return -ENODEV; 2282 return -ENODEV;
2278 } 2283 }
2284 seg = pci_domain_nr(pdev->bus);
2279 bus = pdev->bus->number; 2285 bus = pdev->bus->number;
2280 2286
2281next_imc: 2287next_imc:
2282 sbridge_dev = get_sbridge_dev(bus, dev_descr->dom, multi_bus, sbridge_dev); 2288 sbridge_dev = get_sbridge_dev(seg, bus, dev_descr->dom,
2289 multi_bus, sbridge_dev);
2283 if (!sbridge_dev) { 2290 if (!sbridge_dev) {
2284 /* If the HA1 wasn't found, don't create EDAC second memory controller */ 2291 /* If the HA1 wasn't found, don't create EDAC second memory controller */
2285 if (dev_descr->dom == IMC1 && devno != 1) { 2292 if (dev_descr->dom == IMC1 && devno != 1) {
@@ -2292,7 +2299,7 @@ next_imc:
2292 if (dev_descr->dom == SOCK) 2299 if (dev_descr->dom == SOCK)
2293 goto out_imc; 2300 goto out_imc;
2294 2301
2295 sbridge_dev = alloc_sbridge_dev(bus, dev_descr->dom, table); 2302 sbridge_dev = alloc_sbridge_dev(seg, bus, dev_descr->dom, table);
2296 if (!sbridge_dev) { 2303 if (!sbridge_dev) {
2297 pci_dev_put(pdev); 2304 pci_dev_put(pdev);
2298 return -ENOMEM; 2305 return -ENOMEM;
diff --git a/drivers/edac/thunderx_edac.c b/drivers/edac/thunderx_edac.c
index 4803c6468bab..c009d94f40c5 100644
--- a/drivers/edac/thunderx_edac.c
+++ b/drivers/edac/thunderx_edac.c
@@ -408,26 +408,29 @@ static ssize_t thunderx_lmc_inject_ecc_write(struct file *file,
408 size_t count, loff_t *ppos) 408 size_t count, loff_t *ppos)
409{ 409{
410 struct thunderx_lmc *lmc = file->private_data; 410 struct thunderx_lmc *lmc = file->private_data;
411
412 unsigned int cline_size = cache_line_size(); 411 unsigned int cline_size = cache_line_size();
413 412 u8 *tmp;
414 u8 tmp[cline_size];
415 void __iomem *addr; 413 void __iomem *addr;
416 unsigned int offs, timeout = 100000; 414 unsigned int offs, timeout = 100000;
417 415
418 atomic_set(&lmc->ecc_int, 0); 416 atomic_set(&lmc->ecc_int, 0);
419 417
420 lmc->mem = alloc_pages_node(lmc->node, GFP_KERNEL, 0); 418 lmc->mem = alloc_pages_node(lmc->node, GFP_KERNEL, 0);
421
422 if (!lmc->mem) 419 if (!lmc->mem)
423 return -ENOMEM; 420 return -ENOMEM;
424 421
422 tmp = kmalloc(cline_size, GFP_KERNEL);
423 if (!tmp) {
424 __free_pages(lmc->mem, 0);
425 return -ENOMEM;
426 }
427
425 addr = page_address(lmc->mem); 428 addr = page_address(lmc->mem);
426 429
427 while (!atomic_read(&lmc->ecc_int) && timeout--) { 430 while (!atomic_read(&lmc->ecc_int) && timeout--) {
428 stop_machine(inject_ecc_fn, lmc, NULL); 431 stop_machine(inject_ecc_fn, lmc, NULL);
429 432
430 for (offs = 0; offs < PAGE_SIZE; offs += sizeof(tmp)) { 433 for (offs = 0; offs < PAGE_SIZE; offs += cline_size) {
431 /* 434 /*
432 * Do a load from the previously rigged location 435 * Do a load from the previously rigged location
433 * This should generate an error interrupt. 436 * This should generate an error interrupt.
@@ -437,6 +440,7 @@ static ssize_t thunderx_lmc_inject_ecc_write(struct file *file,
437 } 440 }
438 } 441 }
439 442
443 kfree(tmp);
440 __free_pages(lmc->mem, 0); 444 __free_pages(lmc->mem, 0);
441 445
442 return count; 446 return count;