Skip to content

Commit

Permalink
Merge tag 'powerpc-4.2-2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/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
  • Loading branch information
Linus Torvalds committed Jul 10, 2015
2 parents c4b5fd3 + 2c069a1 commit 3cdeb9d
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 40 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6173,7 +6173,7 @@ M: Michael Ellerman <mpe@ellerman.id.au>
W: http://www.penguinppc.org/
L: linuxppc-dev@lists.ozlabs.org
Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
S: Supported
F: Documentation/powerpc/
F: arch/powerpc/
Expand Down
31 changes: 21 additions & 10 deletions arch/powerpc/kernel/idle_power7.S
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@

.text

/*
* Used by threads when the lock bit of core_idle_state is set.
* Threads will spin in HMT_LOW until the lock bit is cleared.
* r14 - pointer to core_idle_state
* r15 - used to load contents of core_idle_state
*/

core_idle_lock_held:
HMT_LOW
3: lwz r15,0(r14)
andi. r15,r15,PNV_CORE_IDLE_LOCK_BIT
bne 3b
HMT_MEDIUM
lwarx r15,0,r14
blr

/*
* Pass requested state in r3:
* r3 - PNV_THREAD_NAP/SLEEP/WINKLE
Expand Down Expand Up @@ -150,6 +166,10 @@ power7_enter_nap_mode:
ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
lwarx_loop1:
lwarx r15,0,r14

andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
bnel core_idle_lock_held

andc r15,r15,r7 /* Clear thread bit */

andi. r15,r15,PNV_CORE_IDLE_THREAD_BITS
Expand Down Expand Up @@ -294,7 +314,7 @@ lwarx_loop2:
* workaround undo code or resyncing timebase or restoring context
* In either case loop until the lock bit is cleared.
*/
bne core_idle_lock_held
bnel core_idle_lock_held

cmpwi cr2,r15,0
lbz r4,PACA_SUBCORE_SIBLING_MASK(r13)
Expand All @@ -319,15 +339,6 @@ lwarx_loop2:
isync
b common_exit

core_idle_lock_held:
HMT_LOW
core_idle_lock_loop:
lwz r15,0(14)
andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
bne core_idle_lock_loop
HMT_MEDIUM
b lwarx_loop2

first_thread_in_subcore:
/* First thread in subcore to wakeup */
ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ long machine_check_early(struct pt_regs *regs)

__this_cpu_inc(irq_stat.mce_exceptions);

add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);

if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
handled = cur_cpu_spec->machine_check_early(regs);
return handled;
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
printk(KERN_ALERT "Unable to handle kernel paging request for "
"instruction fetch\n");
break;
case 0x600:
printk(KERN_ALERT "Unable to handle kernel paging request for "
"unaligned access at address 0x%08lx\n", regs->dar);
break;
default:
printk(KERN_ALERT "Unable to handle kernel paging request for "
"unknown fault\n");
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/perf/hv-24x7.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ static struct attribute *device_str_attr_create_(char *name, char *str)
if (!attr)
return NULL;

sysfs_attr_init(&attr->attr.attr);

attr->var = str;
attr->attr.attr.name = name;
attr->attr.attr.mode = 0444;
Expand Down
16 changes: 5 additions & 11 deletions arch/powerpc/platforms/powernv/opal-elog.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
return elog;
}

static void elog_work_fn(struct work_struct *work)
static irqreturn_t elog_event(int irq, void *data)
{
__be64 size;
__be64 id;
Expand All @@ -251,7 +251,7 @@ static void elog_work_fn(struct work_struct *work)
rc = opal_get_elog_size(&id, &size, &type);
if (rc != OPAL_SUCCESS) {
pr_err("ELOG: OPAL log info read failed\n");
return;
return IRQ_HANDLED;
}

elog_size = be64_to_cpu(size);
Expand All @@ -270,16 +270,10 @@ static void elog_work_fn(struct work_struct *work)
* entries.
*/
if (kset_find_obj(elog_kset, name))
return;
return IRQ_HANDLED;

create_elog_obj(log_id, elog_size, elog_type);
}

static DECLARE_WORK(elog_work, elog_work_fn);

static irqreturn_t elog_event(int irq, void *data)
{
schedule_work(&elog_work);
return IRQ_HANDLED;
}

Expand All @@ -304,8 +298,8 @@ int __init opal_elog_init(void)
return irq;
}

rc = request_irq(irq, elog_event,
IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL);
rc = request_threaded_irq(irq, NULL, elog_event,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL);
if (rc) {
pr_err("%s: Can't request OPAL event irq (%d)\n",
__func__, rc);
Expand Down
9 changes: 4 additions & 5 deletions arch/powerpc/platforms/powernv/opal-prd.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static int opal_prd_open(struct inode *inode, struct file *file)
static int opal_prd_mmap(struct file *file, struct vm_area_struct *vma)
{
size_t addr, size;
pgprot_t page_prot;
int rc;

pr_devel("opal_prd_mmap(0x%016lx, 0x%016lx, 0x%lx, 0x%lx)\n",
Expand All @@ -125,13 +126,11 @@ static int opal_prd_mmap(struct file *file, struct vm_area_struct *vma)
if (!opal_prd_range_is_valid(addr, size))
return -EINVAL;

vma->vm_page_prot = __pgprot(pgprot_val(phys_mem_access_prot(file,
vma->vm_pgoff,
size, vma->vm_page_prot))
| _PAGE_SPECIAL);
page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
size, vma->vm_page_prot);

rc = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size,
vma->vm_page_prot);
page_prot);

return rc;
}
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/sysdev/ppc4xx_hsta_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/pci.h>
#include <linux/semaphore.h>
#include <asm/msi_bitmap.h>
#include <asm/ppc-pci.h>

struct ppc4xx_hsta_msi {
struct device *dev;
Expand Down
12 changes: 5 additions & 7 deletions drivers/misc/cxl/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)

afu = cxl_pci_to_afu(dev);

get_device(&afu->dev);
ctx = cxl_context_alloc();
if (IS_ERR(ctx))
return ctx;
Expand All @@ -31,6 +32,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
rc = cxl_context_init(ctx, afu, false, NULL);
if (rc) {
kfree(ctx);
put_device(&afu->dev);
return ERR_PTR(-ENOMEM);
}
cxl_assign_psn_space(ctx);
Expand Down Expand Up @@ -60,6 +62,8 @@ int cxl_release_context(struct cxl_context *ctx)
if (ctx->status != CLOSED)
return -EBUSY;

put_device(&ctx->afu->dev);

cxl_context_free(ctx);

return 0;
Expand Down Expand Up @@ -159,7 +163,6 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
}

ctx->status = STARTED;
get_device(&ctx->afu->dev);
out:
mutex_unlock(&ctx->status_mutex);
return rc;
Expand All @@ -175,12 +178,7 @@ EXPORT_SYMBOL_GPL(cxl_process_element);
/* Stop a context. Returns 0 on success, otherwise -Errno */
int cxl_stop_context(struct cxl_context *ctx)
{
int rc;

rc = __detach_context(ctx);
if (!rc)
put_device(&ctx->afu->dev);
return rc;
return __detach_context(ctx);
}
EXPORT_SYMBOL_GPL(cxl_stop_context);

Expand Down
14 changes: 11 additions & 3 deletions drivers/misc/cxl/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)

if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
area = ctx->afu->psn_phys;
if (offset > ctx->afu->adapter->ps_size)
if (offset >= ctx->afu->adapter->ps_size)
return VM_FAULT_SIGBUS;
} else {
area = ctx->psn_phys;
if (offset > ctx->psn_size)
if (offset >= ctx->psn_size)
return VM_FAULT_SIGBUS;
}

Expand Down Expand Up @@ -145,8 +145,16 @@ static const struct vm_operations_struct cxl_mmap_vmops = {
*/
int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
{
u64 start = vma->vm_pgoff << PAGE_SHIFT;
u64 len = vma->vm_end - vma->vm_start;
len = min(len, ctx->psn_size);

if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
if (start + len > ctx->afu->adapter->ps_size)
return -EINVAL;
} else {
if (start + len > ctx->psn_size)
return -EINVAL;
}

if (ctx->afu->current_mode != CXL_MODE_DEDICATED) {
/* make sure there is a valid per process space for this AFU */
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/cxl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static inline void cxl_slbia_core(struct mm_struct *mm)
spin_lock(&adapter->afu_list_lock);
for (slice = 0; slice < adapter->slices; slice++) {
afu = adapter->afu[slice];
if (!afu->enabled)
if (!afu || !afu->enabled)
continue;
rcu_read_lock();
idr_for_each_entry(&afu->contexts_idr, ctx, id)
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/cxl/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct p

static void cxl_unmap_slice_regs(struct cxl_afu *afu)
{
if (afu->p1n_mmio)
if (afu->p2n_mmio)
iounmap(afu->p2n_mmio);
if (afu->p1n_mmio)
iounmap(afu->p1n_mmio);
Expand Down
3 changes: 2 additions & 1 deletion drivers/misc/cxl/vphb.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
unsigned long addr;

phb = pci_bus_to_host(bus);
afu = (struct cxl_afu *)phb->private_data;
if (phb == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
afu = (struct cxl_afu *)phb->private_data;

if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num)
return PCIBIOS_DEVICE_NOT_FOUND;
if (offset >= (unsigned long)phb->cfg_data)
Expand Down

0 comments on commit 3cdeb9d

Please sign in to comment.