aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-10 15:16:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-10 15:16:59 -0400
commit3cdeb9d15149a543f690ac9b2fccb128496dfb06 (patch)
tree67f7e9acadb780c95f1d087eccfdd5227e858e4e
parentc4b5fd3fb2058b650447372472ad24e2a989f9f6 (diff)
parent2c069a118fe1d80c47dca84e1561045fc7f3cc9e (diff)
Merge tag 'powerpc-4.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - opal-prd mmap fix from Vaidy - set kernel taint for MCEs from Daniel - alignment exception description from Anton - ppc4xx_hsta_msi build fix from Daniel - opal-elog interrupt fix from Alistair - core_idle_state race fix from Shreyas - hv-24x7 lockdep fix from Sukadev - multiple cxl fixes from Daniel, Ian, Mikey & Maninder - update MAINTAINERS to point at shared tree * tag 'powerpc-4.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: cxl: Check if afu is not null in cxl_slbia powerpc: Update MAINTAINERS to point at shared tree powerpc/perf/24x7: Fix lockdep warning cxl: Fix off by one error allowing subsequent mmap page to be accessed cxl: Fail mmap if requested mapping is larger than assigned problem state area cxl: Fix refcounting in kernel API powerpc/powernv: Fix race in updating core_idle_state powerpc/powernv: Fix opal-elog interrupt handler powerpc/ppc4xx_hsta_msi: Include ppc-pci.h to fix reference to hose_list powerpc: Add plain English description for alignment exception oopses cxl: Test the correct mmio space before unmapping powerpc: Set the correct kernel taint on machine check errors cxl/vphb.c: Use phb pointer after NULL check powerpc/powernv: Fix vma page prot flags in opal-prd driver
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/powerpc/kernel/idle_power7.S31
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/powerpc/mm/fault.c4
-rw-r--r--arch/powerpc/perf/hv-24x7.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal-elog.c16
-rw-r--r--arch/powerpc/platforms/powernv/opal-prd.c9
-rw-r--r--arch/powerpc/sysdev/ppc4xx_hsta_msi.c1
-rw-r--r--drivers/misc/cxl/api.c12
-rw-r--r--drivers/misc/cxl/context.c14
-rw-r--r--drivers/misc/cxl/main.c2
-rw-r--r--drivers/misc/cxl/pci.c2
-rw-r--r--drivers/misc/cxl/vphb.c3
13 files changed, 60 insertions, 40 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0d70760e8135..10438be21227 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6173,7 +6173,7 @@ M: Michael Ellerman <mpe@ellerman.id.au>
6173W: http://www.penguinppc.org/ 6173W: http://www.penguinppc.org/
6174L: linuxppc-dev@lists.ozlabs.org 6174L: linuxppc-dev@lists.ozlabs.org
6175Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ 6175Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
6176T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git 6176T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
6177S: Supported 6177S: Supported
6178F: Documentation/powerpc/ 6178F: Documentation/powerpc/
6179F: arch/powerpc/ 6179F: arch/powerpc/
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index ccde8f084ce4..112ccf497562 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -52,6 +52,22 @@
52 .text 52 .text
53 53
54/* 54/*
55 * Used by threads when the lock bit of core_idle_state is set.
56 * Threads will spin in HMT_LOW until the lock bit is cleared.
57 * r14 - pointer to core_idle_state
58 * r15 - used to load contents of core_idle_state
59 */
60
61core_idle_lock_held:
62 HMT_LOW
633: lwz r15,0(r14)
64 andi. r15,r15,PNV_CORE_IDLE_LOCK_BIT
65 bne 3b
66 HMT_MEDIUM
67 lwarx r15,0,r14
68 blr
69
70/*
55 * Pass requested state in r3: 71 * Pass requested state in r3:
56 * r3 - PNV_THREAD_NAP/SLEEP/WINKLE 72 * r3 - PNV_THREAD_NAP/SLEEP/WINKLE
57 * 73 *
@@ -150,6 +166,10 @@ power7_enter_nap_mode:
150 ld r14,PACA_CORE_IDLE_STATE_PTR(r13) 166 ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
151lwarx_loop1: 167lwarx_loop1:
152 lwarx r15,0,r14 168 lwarx r15,0,r14
169
170 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
171 bnel core_idle_lock_held
172
153 andc r15,r15,r7 /* Clear thread bit */ 173 andc r15,r15,r7 /* Clear thread bit */
154 174
155 andi. r15,r15,PNV_CORE_IDLE_THREAD_BITS 175 andi. r15,r15,PNV_CORE_IDLE_THREAD_BITS
@@ -294,7 +314,7 @@ lwarx_loop2:
294 * workaround undo code or resyncing timebase or restoring context 314 * workaround undo code or resyncing timebase or restoring context
295 * In either case loop until the lock bit is cleared. 315 * In either case loop until the lock bit is cleared.
296 */ 316 */
297 bne core_idle_lock_held 317 bnel core_idle_lock_held
298 318
299 cmpwi cr2,r15,0 319 cmpwi cr2,r15,0
300 lbz r4,PACA_SUBCORE_SIBLING_MASK(r13) 320 lbz r4,PACA_SUBCORE_SIBLING_MASK(r13)
@@ -319,15 +339,6 @@ lwarx_loop2:
319 isync 339 isync
320 b common_exit 340 b common_exit
321 341
322core_idle_lock_held:
323 HMT_LOW
324core_idle_lock_loop:
325 lwz r15,0(14)
326 andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
327 bne core_idle_lock_loop
328 HMT_MEDIUM
329 b lwarx_loop2
330
331first_thread_in_subcore: 342first_thread_in_subcore:
332 /* First thread in subcore to wakeup */ 343 /* First thread in subcore to wakeup */
333 ori r15,r15,PNV_CORE_IDLE_LOCK_BIT 344 ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6530f1b8874d..37de90f8a845 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -297,6 +297,8 @@ long machine_check_early(struct pt_regs *regs)
297 297
298 __this_cpu_inc(irq_stat.mce_exceptions); 298 __this_cpu_inc(irq_stat.mce_exceptions);
299 299
300 add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
301
300 if (cur_cpu_spec && cur_cpu_spec->machine_check_early) 302 if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
301 handled = cur_cpu_spec->machine_check_early(regs); 303 handled = cur_cpu_spec->machine_check_early(regs);
302 return handled; 304 return handled;
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 6d535973b200..a67c6d781c52 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -529,6 +529,10 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
529 printk(KERN_ALERT "Unable to handle kernel paging request for " 529 printk(KERN_ALERT "Unable to handle kernel paging request for "
530 "instruction fetch\n"); 530 "instruction fetch\n");
531 break; 531 break;
532 case 0x600:
533 printk(KERN_ALERT "Unable to handle kernel paging request for "
534 "unaligned access at address 0x%08lx\n", regs->dar);
535 break;
532 default: 536 default:
533 printk(KERN_ALERT "Unable to handle kernel paging request for " 537 printk(KERN_ALERT "Unable to handle kernel paging request for "
534 "unknown fault\n"); 538 "unknown fault\n");
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index ec2eb20631d1..df956295c2a7 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -320,6 +320,8 @@ static struct attribute *device_str_attr_create_(char *name, char *str)
320 if (!attr) 320 if (!attr)
321 return NULL; 321 return NULL;
322 322
323 sysfs_attr_init(&attr->attr.attr);
324
323 attr->var = str; 325 attr->var = str;
324 attr->attr.attr.name = name; 326 attr->attr.attr.name = name;
325 attr->attr.attr.mode = 0444; 327 attr->attr.attr.mode = 0444;
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 4949ef0d9400..37f959bf392e 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -237,7 +237,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
237 return elog; 237 return elog;
238} 238}
239 239
240static void elog_work_fn(struct work_struct *work) 240static irqreturn_t elog_event(int irq, void *data)
241{ 241{
242 __be64 size; 242 __be64 size;
243 __be64 id; 243 __be64 id;
@@ -251,7 +251,7 @@ static void elog_work_fn(struct work_struct *work)
251 rc = opal_get_elog_size(&id, &size, &type); 251 rc = opal_get_elog_size(&id, &size, &type);
252 if (rc != OPAL_SUCCESS) { 252 if (rc != OPAL_SUCCESS) {
253 pr_err("ELOG: OPAL log info read failed\n"); 253 pr_err("ELOG: OPAL log info read failed\n");
254 return; 254 return IRQ_HANDLED;
255 } 255 }
256 256
257 elog_size = be64_to_cpu(size); 257 elog_size = be64_to_cpu(size);
@@ -270,16 +270,10 @@ static void elog_work_fn(struct work_struct *work)
270 * entries. 270 * entries.
271 */ 271 */
272 if (kset_find_obj(elog_kset, name)) 272 if (kset_find_obj(elog_kset, name))
273 return; 273 return IRQ_HANDLED;
274 274
275 create_elog_obj(log_id, elog_size, elog_type); 275 create_elog_obj(log_id, elog_size, elog_type);
276}
277
278static DECLARE_WORK(elog_work, elog_work_fn);
279 276
280static irqreturn_t elog_event(int irq, void *data)
281{
282 schedule_work(&elog_work);
283 return IRQ_HANDLED; 277 return IRQ_HANDLED;
284} 278}
285 279
@@ -304,8 +298,8 @@ int __init opal_elog_init(void)
304 return irq; 298 return irq;
305 } 299 }
306 300
307 rc = request_irq(irq, elog_event, 301 rc = request_threaded_irq(irq, NULL, elog_event,
308 IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL); 302 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL);
309 if (rc) { 303 if (rc) {
310 pr_err("%s: Can't request OPAL event irq (%d)\n", 304 pr_err("%s: Can't request OPAL event irq (%d)\n",
311 __func__, rc); 305 __func__, rc);
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c
index 46cb3feb0a13..4ece8e40dd54 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -112,6 +112,7 @@ static int opal_prd_open(struct inode *inode, struct file *file)
112static int opal_prd_mmap(struct file *file, struct vm_area_struct *vma) 112static int opal_prd_mmap(struct file *file, struct vm_area_struct *vma)
113{ 113{
114 size_t addr, size; 114 size_t addr, size;
115 pgprot_t page_prot;
115 int rc; 116 int rc;
116 117
117 pr_devel("opal_prd_mmap(0x%016lx, 0x%016lx, 0x%lx, 0x%lx)\n", 118 pr_devel("opal_prd_mmap(0x%016lx, 0x%016lx, 0x%lx, 0x%lx)\n",
@@ -125,13 +126,11 @@ static int opal_prd_mmap(struct file *file, struct vm_area_struct *vma)
125 if (!opal_prd_range_is_valid(addr, size)) 126 if (!opal_prd_range_is_valid(addr, size))
126 return -EINVAL; 127 return -EINVAL;
127 128
128 vma->vm_page_prot = __pgprot(pgprot_val(phys_mem_access_prot(file, 129 page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
129 vma->vm_pgoff, 130 size, vma->vm_page_prot);
130 size, vma->vm_page_prot))
131 | _PAGE_SPECIAL);
132 131
133 rc = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, 132 rc = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size,
134 vma->vm_page_prot); 133 page_prot);
135 134
136 return rc; 135 return rc;
137} 136}
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index 2bc33674ebfc..87f9623ca805 100644
--- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -18,6 +18,7 @@
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/semaphore.h> 19#include <linux/semaphore.h>
20#include <asm/msi_bitmap.h> 20#include <asm/msi_bitmap.h>
21#include <asm/ppc-pci.h>
21 22
22struct ppc4xx_hsta_msi { 23struct ppc4xx_hsta_msi {
23 struct device *dev; 24 struct device *dev;
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index 0c77240ae2fc..729e0851167d 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -23,6 +23,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
23 23
24 afu = cxl_pci_to_afu(dev); 24 afu = cxl_pci_to_afu(dev);
25 25
26 get_device(&afu->dev);
26 ctx = cxl_context_alloc(); 27 ctx = cxl_context_alloc();
27 if (IS_ERR(ctx)) 28 if (IS_ERR(ctx))
28 return ctx; 29 return ctx;
@@ -31,6 +32,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
31 rc = cxl_context_init(ctx, afu, false, NULL); 32 rc = cxl_context_init(ctx, afu, false, NULL);
32 if (rc) { 33 if (rc) {
33 kfree(ctx); 34 kfree(ctx);
35 put_device(&afu->dev);
34 return ERR_PTR(-ENOMEM); 36 return ERR_PTR(-ENOMEM);
35 } 37 }
36 cxl_assign_psn_space(ctx); 38 cxl_assign_psn_space(ctx);
@@ -60,6 +62,8 @@ int cxl_release_context(struct cxl_context *ctx)
60 if (ctx->status != CLOSED) 62 if (ctx->status != CLOSED)
61 return -EBUSY; 63 return -EBUSY;
62 64
65 put_device(&ctx->afu->dev);
66
63 cxl_context_free(ctx); 67 cxl_context_free(ctx);
64 68
65 return 0; 69 return 0;
@@ -159,7 +163,6 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
159 } 163 }
160 164
161 ctx->status = STARTED; 165 ctx->status = STARTED;
162 get_device(&ctx->afu->dev);
163out: 166out:
164 mutex_unlock(&ctx->status_mutex); 167 mutex_unlock(&ctx->status_mutex);
165 return rc; 168 return rc;
@@ -175,12 +178,7 @@ EXPORT_SYMBOL_GPL(cxl_process_element);
175/* Stop a context. Returns 0 on success, otherwise -Errno */ 178/* Stop a context. Returns 0 on success, otherwise -Errno */
176int cxl_stop_context(struct cxl_context *ctx) 179int cxl_stop_context(struct cxl_context *ctx)
177{ 180{
178 int rc; 181 return __detach_context(ctx);
179
180 rc = __detach_context(ctx);
181 if (!rc)
182 put_device(&ctx->afu->dev);
183 return rc;
184} 182}
185EXPORT_SYMBOL_GPL(cxl_stop_context); 183EXPORT_SYMBOL_GPL(cxl_stop_context);
186 184
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 2a4c80ac322a..1287148629c0 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -113,11 +113,11 @@ static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
113 113
114 if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { 114 if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
115 area = ctx->afu->psn_phys; 115 area = ctx->afu->psn_phys;
116 if (offset > ctx->afu->adapter->ps_size) 116 if (offset >= ctx->afu->adapter->ps_size)
117 return VM_FAULT_SIGBUS; 117 return VM_FAULT_SIGBUS;
118 } else { 118 } else {
119 area = ctx->psn_phys; 119 area = ctx->psn_phys;
120 if (offset > ctx->psn_size) 120 if (offset >= ctx->psn_size)
121 return VM_FAULT_SIGBUS; 121 return VM_FAULT_SIGBUS;
122 } 122 }
123 123
@@ -145,8 +145,16 @@ static const struct vm_operations_struct cxl_mmap_vmops = {
145 */ 145 */
146int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma) 146int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
147{ 147{
148 u64 start = vma->vm_pgoff << PAGE_SHIFT;
148 u64 len = vma->vm_end - vma->vm_start; 149 u64 len = vma->vm_end - vma->vm_start;
149 len = min(len, ctx->psn_size); 150
151 if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
152 if (start + len > ctx->afu->adapter->ps_size)
153 return -EINVAL;
154 } else {
155 if (start + len > ctx->psn_size)
156 return -EINVAL;
157 }
150 158
151 if (ctx->afu->current_mode != CXL_MODE_DEDICATED) { 159 if (ctx->afu->current_mode != CXL_MODE_DEDICATED) {
152 /* make sure there is a valid per process space for this AFU */ 160 /* make sure there is a valid per process space for this AFU */
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index 833348e2c9cb..4a164ab8b35a 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -73,7 +73,7 @@ static inline void cxl_slbia_core(struct mm_struct *mm)
73 spin_lock(&adapter->afu_list_lock); 73 spin_lock(&adapter->afu_list_lock);
74 for (slice = 0; slice < adapter->slices; slice++) { 74 for (slice = 0; slice < adapter->slices; slice++) {
75 afu = adapter->afu[slice]; 75 afu = adapter->afu[slice];
76 if (!afu->enabled) 76 if (!afu || !afu->enabled)
77 continue; 77 continue;
78 rcu_read_lock(); 78 rcu_read_lock();
79 idr_for_each_entry(&afu->contexts_idr, ctx, id) 79 idr_for_each_entry(&afu->contexts_idr, ctx, id)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index c68ef5806dbe..32ad09705949 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -539,7 +539,7 @@ err:
539 539
540static void cxl_unmap_slice_regs(struct cxl_afu *afu) 540static void cxl_unmap_slice_regs(struct cxl_afu *afu)
541{ 541{
542 if (afu->p1n_mmio) 542 if (afu->p2n_mmio)
543 iounmap(afu->p2n_mmio); 543 iounmap(afu->p2n_mmio);
544 if (afu->p1n_mmio) 544 if (afu->p1n_mmio)
545 iounmap(afu->p1n_mmio); 545 iounmap(afu->p1n_mmio);
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index b1d1983a84a5..2eba002b580b 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -112,9 +112,10 @@ static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
112 unsigned long addr; 112 unsigned long addr;
113 113
114 phb = pci_bus_to_host(bus); 114 phb = pci_bus_to_host(bus);
115 afu = (struct cxl_afu *)phb->private_data;
116 if (phb == NULL) 115 if (phb == NULL)
117 return PCIBIOS_DEVICE_NOT_FOUND; 116 return PCIBIOS_DEVICE_NOT_FOUND;
117 afu = (struct cxl_afu *)phb->private_data;
118
118 if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num) 119 if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num)
119 return PCIBIOS_DEVICE_NOT_FOUND; 120 return PCIBIOS_DEVICE_NOT_FOUND;
120 if (offset >= (unsigned long)phb->cfg_data) 121 if (offset >= (unsigned long)phb->cfg_data)