提交 4645453c 编写于 作者: L Linus Torvalds

Merge tag 'powerpc-4.20-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:
 "One notable fix for our change to split pt_regs between user/kernel,
  we forgot to update BPF to use the user-visible type which was an ABI
  break for BPF programs.

  A slightly ugly but minimal fix to do_syscall_trace_enter() so that we
  use tracehook_report_syscall_entry() properly. We'll rework the code
  in next to avoid the empty if body.

  Seven commits fixing bugs in the new papr_scm (Storage Class Memory)
  driver. The driver was finally able to be tested on the other
  hypervisor which exposed several bugs. The fixes are all fairly
  minimal at least.

  Fix a crash in our MSI code if an MSI-capable device is plugged into a
  non-MSI capable PHB, only seen on older hardware (MPC8378).

  Fix our legacy serial code to look for "stdout-path" since the device
  trees were updated to use that instead of "linux,stdout-path".

  A change to the COFF zImage code to fix booting old powermacs.

  A couple of minor build fixes.

  Thanks to: Benjamin Herrenschmidt, Daniel Axtens, Dmitry V. Levin,
  Elvira Khabirova, Oliver O'Halloran, Paul Mackerras, Radu Rendec, Rob
  Herring, Sandipan Das"

* tag 'powerpc-4.20-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
  powerpc/mm: Fallback to RAM if the altmap is unusable
  powerpc/papr_scm: Use ibm,unit-guid as the iset cookie
  powerpc/papr_scm: Fix DIMM device registration race
  powerpc/papr_scm: Remove endian conversions
  powerpc/papr_scm: Update DT properties
  powerpc/papr_scm: Fix resource end address
  powerpc/papr_scm: Use depend instead of select
  powerpc/bpf: Fix broken uapi for BPF_PROG_TYPE_PERF_EVENT
  powerpc/boot: Fix build failures with -j 1
  powerpc: Look for "stdout-path" when setting up legacy consoles
  powerpc/msi: Fix NULL pointer access in teardown code
  powerpc/mm: Fix linux page tables build with some configs
  powerpc: Fix COFF zImage booting on old powermacs
...@@ -197,7 +197,7 @@ $(obj)/empty.c: ...@@ -197,7 +197,7 @@ $(obj)/empty.c:
$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
$(Q)cp $< $@ $(Q)cp $< $@
$(obj)/serial.c: $(obj)/autoconf.h $(srctree)/$(src)/serial.c: $(obj)/autoconf.h
$(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/% $(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/%
$(Q)cp $< $@ $(Q)cp $< $@
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
RELA = 7 RELA = 7
RELACOUNT = 0x6ffffff9 RELACOUNT = 0x6ffffff9
.text .data
/* A procedure descriptor used when booting this as a COFF file. /* A procedure descriptor used when booting this as a COFF file.
* When making COFF, this comes first in the link and we're * When making COFF, this comes first in the link and we're
* linked at 0x500000. * linked at 0x500000.
...@@ -23,6 +23,8 @@ RELACOUNT = 0x6ffffff9 ...@@ -23,6 +23,8 @@ RELACOUNT = 0x6ffffff9
.globl _zimage_start_opd .globl _zimage_start_opd
_zimage_start_opd: _zimage_start_opd:
.long 0x500000, 0, 0, 0 .long 0x500000, 0, 0, 0
.text
b _zimage_start
#ifdef __powerpc64__ #ifdef __powerpc64__
.balign 8 .balign 8
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/reg.h> #include <asm/reg.h>
#define perf_arch_bpf_user_pt_regs(regs) &regs->user_regs
/* /*
* Overload regs->result to specify whether we should use the MSR (result * Overload regs->result to specify whether we should use the MSR (result
* is zero) or the SIAR (result is non zero). * is zero) or the SIAR (result is non zero).
......
# UAPI Header export list # UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm include include/uapi/asm-generic/Kbuild.asm
generic-y += bpf_perf_event.h
generic-y += param.h generic-y += param.h
generic-y += poll.h generic-y += poll.h
generic-y += resource.h generic-y += resource.h
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__
#include <asm/ptrace.h>
typedef struct user_pt_regs bpf_user_pt_regs_t;
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
...@@ -372,6 +372,8 @@ void __init find_legacy_serial_ports(void) ...@@ -372,6 +372,8 @@ void __init find_legacy_serial_ports(void)
/* Now find out if one of these is out firmware console */ /* Now find out if one of these is out firmware console */
path = of_get_property(of_chosen, "linux,stdout-path", NULL); path = of_get_property(of_chosen, "linux,stdout-path", NULL);
if (path == NULL)
path = of_get_property(of_chosen, "stdout-path", NULL);
if (path != NULL) { if (path != NULL) {
stdout = of_find_node_by_path(path); stdout = of_find_node_by_path(path);
if (stdout) if (stdout)
...@@ -595,8 +597,10 @@ static int __init check_legacy_serial_console(void) ...@@ -595,8 +597,10 @@ static int __init check_legacy_serial_console(void)
/* We are getting a weird phandle from OF ... */ /* We are getting a weird phandle from OF ... */
/* ... So use the full path instead */ /* ... So use the full path instead */
name = of_get_property(of_chosen, "linux,stdout-path", NULL); name = of_get_property(of_chosen, "linux,stdout-path", NULL);
if (name == NULL)
name = of_get_property(of_chosen, "stdout-path", NULL);
if (name == NULL) { if (name == NULL) {
DBG(" no linux,stdout-path !\n"); DBG(" no stdout-path !\n");
return -ENODEV; return -ENODEV;
} }
prom_stdout = of_find_node_by_path(name); prom_stdout = of_find_node_by_path(name);
......
...@@ -34,5 +34,10 @@ void arch_teardown_msi_irqs(struct pci_dev *dev) ...@@ -34,5 +34,10 @@ void arch_teardown_msi_irqs(struct pci_dev *dev)
{ {
struct pci_controller *phb = pci_bus_to_host(dev->bus); struct pci_controller *phb = pci_bus_to_host(dev->bus);
phb->controller_ops.teardown_msi_irqs(dev); /*
* We can be called even when arch_setup_msi_irqs() returns -ENOSYS,
* so check the pointer again.
*/
if (phb->controller_ops.teardown_msi_irqs)
phb->controller_ops.teardown_msi_irqs(dev);
} }
...@@ -3266,12 +3266,17 @@ long do_syscall_trace_enter(struct pt_regs *regs) ...@@ -3266,12 +3266,17 @@ long do_syscall_trace_enter(struct pt_regs *regs)
user_exit(); user_exit();
if (test_thread_flag(TIF_SYSCALL_EMU)) { if (test_thread_flag(TIF_SYSCALL_EMU)) {
ptrace_report_syscall(regs);
/* /*
* A nonzero return code from tracehook_report_syscall_entry()
* tells us to prevent the syscall execution, but we are not
* going to execute it anyway.
*
* Returning -1 will skip the syscall execution. We want to * Returning -1 will skip the syscall execution. We want to
* avoid clobbering any register also, thus, not 'gotoing' * avoid clobbering any register also, thus, not 'gotoing'
* skip label. * skip label.
*/ */
if (tracehook_report_syscall_entry(regs))
;
return -1; return -1;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
......
...@@ -188,15 +188,20 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, ...@@ -188,15 +188,20 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
for (; start < end; start += page_size) { for (; start < end; start += page_size) {
void *p; void *p = NULL;
int rc; int rc;
if (vmemmap_populated(start, page_size)) if (vmemmap_populated(start, page_size))
continue; continue;
/*
* Allocate from the altmap first if we have one. This may
* fail due to alignment issues when using 16MB hugepages, so
* fall back to system memory if the altmap allocation fail.
*/
if (altmap) if (altmap)
p = altmap_alloc_block_buf(page_size, altmap); p = altmap_alloc_block_buf(page_size, altmap);
else if (!p)
p = vmemmap_alloc_block_buf(page_size, node); p = vmemmap_alloc_block_buf(page_size, node);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
...@@ -255,8 +260,15 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, ...@@ -255,8 +260,15 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
{ {
unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
unsigned long page_order = get_order(page_size); unsigned long page_order = get_order(page_size);
unsigned long alt_start = ~0, alt_end = ~0;
unsigned long base_pfn;
start = _ALIGN_DOWN(start, page_size); start = _ALIGN_DOWN(start, page_size);
if (altmap) {
alt_start = altmap->base_pfn;
alt_end = altmap->base_pfn + altmap->reserve +
altmap->free + altmap->alloc + altmap->align;
}
pr_debug("vmemmap_free %lx...%lx\n", start, end); pr_debug("vmemmap_free %lx...%lx\n", start, end);
...@@ -280,8 +292,9 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, ...@@ -280,8 +292,9 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
page = pfn_to_page(addr >> PAGE_SHIFT); page = pfn_to_page(addr >> PAGE_SHIFT);
section_base = pfn_to_page(vmemmap_section_start(start)); section_base = pfn_to_page(vmemmap_section_start(start));
nr_pages = 1 << page_order; nr_pages = 1 << page_order;
base_pfn = PHYS_PFN(addr);
if (altmap) { if (base_pfn >= alt_start && base_pfn < alt_end) {
vmem_altmap_free(altmap, nr_pages); vmem_altmap_free(altmap, nr_pages);
} else if (PageReserved(page)) { } else if (PageReserved(page)) {
/* allocated from bootmem */ /* allocated from bootmem */
......
...@@ -140,8 +140,7 @@ config IBMEBUS ...@@ -140,8 +140,7 @@ config IBMEBUS
Bus device driver for GX bus based adapters. Bus device driver for GX bus based adapters.
config PAPR_SCM config PAPR_SCM
depends on PPC_PSERIES && MEMORY_HOTPLUG depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM
select LIBNVDIMM
tristate "Support for the PAPR Storage Class Memory interface" tristate "Support for the PAPR Storage Class Memory interface"
help help
Enable access to hypervisor provided storage class memory. Enable access to hypervisor provided storage class memory.
...@@ -55,7 +55,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p) ...@@ -55,7 +55,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
do { do {
rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0, rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
p->blocks, BIND_ANY_ADDR, token); p->blocks, BIND_ANY_ADDR, token);
token = be64_to_cpu(ret[0]); token = ret[0];
cond_resched(); cond_resched();
} while (rc == H_BUSY); } while (rc == H_BUSY);
...@@ -64,7 +64,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p) ...@@ -64,7 +64,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
return -ENXIO; return -ENXIO;
} }
p->bound_addr = be64_to_cpu(ret[1]); p->bound_addr = ret[1];
dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res); dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);
...@@ -82,7 +82,7 @@ static int drc_pmem_unbind(struct papr_scm_priv *p) ...@@ -82,7 +82,7 @@ static int drc_pmem_unbind(struct papr_scm_priv *p)
do { do {
rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index, rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index,
p->bound_addr, p->blocks, token); p->bound_addr, p->blocks, token);
token = be64_to_cpu(ret); token = ret[0];
cond_resched(); cond_resched();
} while (rc == H_BUSY); } while (rc == H_BUSY);
...@@ -223,6 +223,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) ...@@ -223,6 +223,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
goto err; goto err;
} }
if (nvdimm_bus_check_dimm_count(p->bus, 1))
goto err;
/* now add the region */ /* now add the region */
memset(&mapping, 0, sizeof(mapping)); memset(&mapping, 0, sizeof(mapping));
...@@ -257,9 +260,12 @@ err: nvdimm_bus_unregister(p->bus); ...@@ -257,9 +260,12 @@ err: nvdimm_bus_unregister(p->bus);
static int papr_scm_probe(struct platform_device *pdev) static int papr_scm_probe(struct platform_device *pdev)
{ {
uint32_t drc_index, metadata_size, unit_cap[2];
struct device_node *dn = pdev->dev.of_node; struct device_node *dn = pdev->dev.of_node;
u32 drc_index, metadata_size;
u64 blocks, block_size;
struct papr_scm_priv *p; struct papr_scm_priv *p;
const char *uuid_str;
u64 uuid[2];
int rc; int rc;
/* check we have all the required DT properties */ /* check we have all the required DT properties */
...@@ -268,8 +274,18 @@ static int papr_scm_probe(struct platform_device *pdev) ...@@ -268,8 +274,18 @@ static int papr_scm_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
if (of_property_read_u32_array(dn, "ibm,unit-capacity", unit_cap, 2)) { if (of_property_read_u64(dn, "ibm,block-size", &block_size)) {
dev_err(&pdev->dev, "%pOF: missing unit-capacity!\n", dn); dev_err(&pdev->dev, "%pOF: missing block-size!\n", dn);
return -ENODEV;
}
if (of_property_read_u64(dn, "ibm,number-of-blocks", &blocks)) {
dev_err(&pdev->dev, "%pOF: missing number-of-blocks!\n", dn);
return -ENODEV;
}
if (of_property_read_string(dn, "ibm,unit-guid", &uuid_str)) {
dev_err(&pdev->dev, "%pOF: missing unit-guid!\n", dn);
return -ENODEV; return -ENODEV;
} }
...@@ -282,8 +298,13 @@ static int papr_scm_probe(struct platform_device *pdev) ...@@ -282,8 +298,13 @@ static int papr_scm_probe(struct platform_device *pdev)
p->dn = dn; p->dn = dn;
p->drc_index = drc_index; p->drc_index = drc_index;
p->block_size = unit_cap[0]; p->block_size = block_size;
p->blocks = unit_cap[1]; p->blocks = blocks;
/* We just need to ensure that set cookies are unique across */
uuid_parse(uuid_str, (uuid_t *) uuid);
p->nd_set.cookie1 = uuid[0];
p->nd_set.cookie2 = uuid[1];
/* might be zero */ /* might be zero */
p->metadata_size = metadata_size; p->metadata_size = metadata_size;
...@@ -296,7 +317,7 @@ static int papr_scm_probe(struct platform_device *pdev) ...@@ -296,7 +317,7 @@ static int papr_scm_probe(struct platform_device *pdev)
/* setup the resource for the newly bound range */ /* setup the resource for the newly bound range */
p->res.start = p->bound_addr; p->res.start = p->bound_addr;
p->res.end = p->bound_addr + p->blocks * p->block_size; p->res.end = p->bound_addr + p->blocks * p->block_size - 1;
p->res.name = pdev->name; p->res.name = pdev->name;
p->res.flags = IORESOURCE_MEM; p->res.flags = IORESOURCE_MEM;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册