summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/cputable.c16
-rw-r--r--arch/powerpc/kernel/iommu.c36
-rw-r--r--arch/powerpc/kernel/kprobes.c14
-rw-r--r--arch/powerpc/kernel/module_64.c16
-rw-r--r--arch/powerpc/kernel/pci_iommu.c40
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/prom.c72
-rw-r--r--arch/powerpc/kernel/prom_init.c112
-rw-r--r--arch/powerpc/kernel/ptrace.c5
-rw-r--r--arch/powerpc/kernel/setup-common.c8
-rw-r--r--arch/powerpc/kernel/setup_64.c8
-rw-r--r--arch/powerpc/kernel/sysfs.c22
-rw-r--r--arch/powerpc/kernel/systbl.S19
-rw-r--r--arch/powerpc/kernel/vio.c6
14 files changed, 329 insertions, 46 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 39e348a3ade..3f7182db9ed 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -57,6 +57,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
+#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
+ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE)
@@ -263,6 +265,20 @@ struct cpu_spec cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4,
.platform = "power5+",
},
+ { /* Power6 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003e0000,
+ .cpu_name = "POWER6",
+ .cpu_features = CPU_FTRS_POWER6,
+ .cpu_user_features = COMMON_USER_POWER6,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+ .oprofile_cpu_type = "ppc64/power6",
+ .oprofile_type = PPC_OPROFILE_POWER4,
+ .platform = "power6",
+ },
{ /* Cell Broadband Engine */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00700000,
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index d9a7fdef59b..4eba60a3289 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -61,6 +61,7 @@ __setup("iommu=", setup_iommu);
static unsigned long iommu_range_alloc(struct iommu_table *tbl,
unsigned long npages,
unsigned long *handle,
+ unsigned long mask,
unsigned int align_order)
{
unsigned long n, end, i, start;
@@ -97,9 +98,21 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
*/
if (start >= limit)
start = largealloc ? tbl->it_largehint : tbl->it_hint;
-
+
again:
+ if (limit + tbl->it_offset > mask) {
+ limit = mask - tbl->it_offset + 1;
+ /* If we're constrained on address range, first try
+ * at the masked hint to avoid O(n) search complexity,
+ * but on second pass, start at 0.
+ */
+ if ((start & mask) >= limit || pass > 0)
+ start = 0;
+ else
+ start &= mask;
+ }
+
n = find_next_zero_bit(tbl->it_map, limit, start);
/* Align allocation */
@@ -150,14 +163,14 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
unsigned int npages, enum dma_data_direction direction,
- unsigned int align_order)
+ unsigned long mask, unsigned int align_order)
{
unsigned long entry, flags;
dma_addr_t ret = DMA_ERROR_CODE;
-
+
spin_lock_irqsave(&(tbl->it_lock), flags);
- entry = iommu_range_alloc(tbl, npages, NULL, align_order);
+ entry = iommu_range_alloc(tbl, npages, NULL, mask, align_order);
if (unlikely(entry == DMA_ERROR_CODE)) {
spin_unlock_irqrestore(&(tbl->it_lock), flags);
@@ -236,7 +249,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
struct scatterlist *sglist, int nelems,
- enum dma_data_direction direction)
+ unsigned long mask, enum dma_data_direction direction)
{
dma_addr_t dma_next = 0, dma_addr;
unsigned long flags;
@@ -274,7 +287,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
vaddr = (unsigned long)page_address(s->page) + s->offset;
npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
npages >>= PAGE_SHIFT;
- entry = iommu_range_alloc(tbl, npages, &handle, 0);
+ entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0);
DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
@@ -479,7 +492,8 @@ void iommu_free_table(struct device_node *dn)
* byte within the page as vaddr.
*/
dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
- size_t size, enum dma_data_direction direction)
+ size_t size, unsigned long mask,
+ enum dma_data_direction direction)
{
dma_addr_t dma_handle = DMA_ERROR_CODE;
unsigned long uaddr;
@@ -492,7 +506,8 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
npages >>= PAGE_SHIFT;
if (tbl) {
- dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0);
+ dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
+ mask >> PAGE_SHIFT, 0);
if (dma_handle == DMA_ERROR_CODE) {
if (printk_ratelimit()) {
printk(KERN_INFO "iommu_alloc failed, "
@@ -521,7 +536,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
* to the dma address (mapping) of the first page.
*/
void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
+ dma_addr_t *dma_handle, unsigned long mask, gfp_t flag)
{
void *ret = NULL;
dma_addr_t mapping;
@@ -551,7 +566,8 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
memset(ret, 0, size);
/* Set up tces to cover the allocated range */
- mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order);
+ mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL,
+ mask >> PAGE_SHIFT, order);
if (mapping == DMA_ERROR_CODE) {
free_pages((unsigned long)ret, order);
ret = NULL;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 856ef1a832b..f78866367b7 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -90,15 +90,15 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
- kprobe_opcode_t insn = *p->ainsn.insn;
-
regs->msr |= MSR_SE;
- /* single step inline if it is a trap variant */
- if (is_trap(insn))
- regs->nip = (unsigned long)p->addr;
- else
- regs->nip = (unsigned long)p->ainsn.insn;
+ /*
+ * On powerpc we should single step on the original
+ * instruction even if the probed insn is a trap
+ * variant as values in regs could play a part in
+ * if the trap is taken or not
+ */
+ regs->nip = (unsigned long)p->ainsn.insn;
}
static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 928b8581fcb..ba34001fca8 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
(void *)hdr
+ sechdrs[sechdrs[i].sh_link].sh_offset);
}
- if (!me->arch.stubs_section || !me->arch.toc_section) {
- printk("%s: doesn't contain .toc or .stubs.\n", me->name);
+
+ if (!me->arch.stubs_section) {
+ printk("%s: doesn't contain .stubs.\n", me->name);
return -ENOEXEC;
}
+ /* If we don't have a .toc, just use .stubs. We need to set r2
+ to some reasonable value in case the module calls out to
+ other functions via a stub, or if a function pointer escapes
+ the module by some means. */
+ if (!me->arch.toc_section)
+ me->arch.toc_section = me->arch.stubs_section;
+
/* Override the stubs size */
sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
return 0;
@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break;
case R_PPC64_TOC16:
- /* Subtact TOC pointer */
+ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me);
if (value + 0x8000 > 0xffff) {
printk("%s: bad TOC16 relocation (%lu)\n",
@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break;
case R_PPC64_TOC16_DS:
- /* Subtact TOC pointer */
+ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me);
if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
printk("%s: bad TOC16_DS relocation (%lu)\n",
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
index c336f3e31cf..c1d95e14bbe 100644
--- a/arch/powerpc/kernel/pci_iommu.c
+++ b/arch/powerpc/kernel/pci_iommu.c
@@ -59,6 +59,25 @@ static inline struct iommu_table *devnode_table(struct device *dev)
}
+static inline unsigned long device_to_mask(struct device *hwdev)
+{
+ struct pci_dev *pdev;
+
+ if (!hwdev) {
+ pdev = ppc64_isabridge_dev;
+ if (!pdev) /* This is the best guess we can do */
+ return 0xfffffffful;
+ } else
+ pdev = to_pci_dev(hwdev);
+
+ if (pdev->dma_mask)
+ return pdev->dma_mask;
+
+ /* Assume devices without mask can take 32 bit addresses */
+ return 0xfffffffful;
+}
+
+
/* Allocates a contiguous real buffer and creates mappings over it.
* Returns the virtual address of the buffer and sets dma_handle
* to the dma address (mapping) of the first page.
@@ -67,7 +86,7 @@ static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
- flag);
+ device_to_mask(hwdev), flag);
}
static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
@@ -85,7 +104,8 @@ static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
size_t size, enum dma_data_direction direction)
{
- return iommu_map_single(devnode_table(hwdev), vaddr, size, direction);
+ return iommu_map_single(devnode_table(hwdev), vaddr, size,
+ device_to_mask(hwdev), direction);
}
@@ -100,7 +120,7 @@ static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction)
{
return iommu_map_sg(pdev, devnode_table(pdev), sglist,
- nelems, direction);
+ nelems, device_to_mask(pdev), direction);
}
static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
@@ -112,7 +132,19 @@ static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
/* We support DMA to/from any memory page via the iommu */
static int pci_iommu_dma_supported(struct device *dev, u64 mask)
{
- return 1;
+ struct iommu_table *tbl = devnode_table(dev);
+
+ if (!tbl || tbl->it_offset > mask) {
+ printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
+ if (tbl)
+ printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
+ mask, tbl->it_offset);
+ else
+ printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
+ mask);
+ return 0;
+ } else
+ return 1;
}
void pci_iommu_init(void)
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index dfa5398ab3c..4b052ae5dc3 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -81,6 +81,7 @@ EXPORT_SYMBOL(strcat);
EXPORT_SYMBOL(strlen);
EXPORT_SYMBOL(strcmp);
EXPORT_SYMBOL(strcasecmp);
+EXPORT_SYMBOL(strncasecmp);
EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4336390bcf3..9a07f97f071 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -62,7 +62,7 @@ static int __initdata dt_root_addr_cells;
static int __initdata dt_root_size_cells;
#ifdef CONFIG_PPC64
-static int __initdata iommu_is_off;
+int __initdata iommu_is_off;
int __initdata iommu_force_on;
unsigned long tce_alloc_start, tce_alloc_end;
#endif
@@ -885,6 +885,74 @@ void __init unflatten_device_tree(void)
DBG(" <- unflatten_device_tree()\n");
}
+/*
+ * ibm,pa-features is a per-cpu property that contains a string of
+ * attribute descriptors, each of which has a 2 byte header plus up
+ * to 254 bytes worth of processor attribute bits. First header
+ * byte specifies the number of bytes following the header.
+ * Second header byte is an "attribute-specifier" type, of which
+ * zero is the only currently-defined value.
+ * Implementation: Pass in the byte and bit offset for the feature
+ * that we are interested in. The function will return -1 if the
+ * pa-features property is missing, or a 1/0 to indicate if the feature
+ * is supported/not supported. Note that the bit numbers are
+ * big-endian to match the definition in PAPR.
+ */
+static struct ibm_pa_feature {
+ unsigned long cpu_features; /* CPU_FTR_xxx bit */
+ unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */
+ unsigned char pabyte; /* byte number in ibm,pa-features */
+ unsigned char pabit; /* bit number (big-endian) */
+ unsigned char invert; /* if 1, pa bit set => clear feature */
+} ibm_pa_features[] __initdata = {
+ {0, PPC_FEATURE_HAS_MMU, 0, 0, 0},
+ {0, PPC_FEATURE_HAS_FPU, 0, 1, 0},
+ {CPU_FTR_SLB, 0, 0, 2, 0},
+ {CPU_FTR_CTRL, 0, 0, 3, 0},
+ {CPU_FTR_NOEXECUTE, 0, 0, 6, 0},
+ {CPU_FTR_NODSISRALIGN, 0, 1, 1, 1},
+ {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
+};
+
+static void __init check_cpu_pa_features(unsigned long node)
+{
+ unsigned char *pa_ftrs;
+ unsigned long len, tablelen, i, bit;
+
+ pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
+ if (pa_ftrs == NULL)
+ return;
+
+ /* find descriptor with type == 0 */
+ for (;;) {
+ if (tablelen < 3)
+ return;
+ len = 2 + pa_ftrs[0];
+ if (tablelen < len)
+ return; /* descriptor 0 not found */
+ if (pa_ftrs[1] == 0)
+ break;
+ tablelen -= len;
+ pa_ftrs += len;
+ }
+
+ /* loop over bits we know about */
+ for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) {
+ struct ibm_pa_feature *fp = &ibm_pa_features[i];
+
+ if (fp->pabyte >= pa_ftrs[0])
+ continue;
+ bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
+ if (bit ^ fp->invert) {
+ cur_cpu_spec->cpu_features |= fp->cpu_features;
+ cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
+ } else {
+ cur_cpu_spec->cpu_features &= ~fp->cpu_features;
+ cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
+ }
+ }
+}
+
static int __init early_init_dt_scan_cpus(unsigned long node,
const char *uname, int depth,
void *data)
@@ -969,6 +1037,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
}
#endif /* CONFIG_ALTIVEC */
+ check_cpu_pa_features(node);
+
#ifdef CONFIG_PPC_PSERIES
if (nthreads > 1)
cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7e4d54821a0..078fb553354 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -636,10 +636,96 @@ static void __init early_cmdline_parse(void)
#ifdef CONFIG_PPC_PSERIES
/*
- * To tell the firmware what our capabilities are, we have to pass
- * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
- * that contain structures that contain the actual values.
+ * There are two methods for telling firmware what our capabilities are.
+ * Newer machines have an "ibm,client-architecture-support" method on the
+ * root node. For older machines, we have to call the "process-elf-header"
+ * method in the /packages/elf-loader node, passing it a fake 32-bit
+ * ELF header containing a couple of PT_NOTE sections that contain
+ * structures that contain various information.
*/
+
+/*
+ * New method - extensible architecture description vector.
+ *
+ * Because the description vector contains a mix of byte and word
+ * values, we declare it as an unsigned char array, and use this
+ * macro to put word values in.
+ */
+#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
+ ((x) >> 8) & 0xff, (x) & 0xff
+
+/* Option vector bits - generic bits in byte 1 */
+#define OV_IGNORE 0x80 /* ignore this vector */
+#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
+
+/* Option vector 1: processor architectures supported */
+#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
+#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
+#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
+#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
+#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
+#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
+
+/* Option vector 2: Open Firmware options supported */
+#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
+
+/* Option vector 3: processor options supported */
+#define OV3_FP 0x80 /* floating point */
+#define OV3_VMX 0x40 /* VMX/Altivec */
+
+/* Option vector 5: PAPR/OF options supported */
+#define OV5_LPAR 0x80 /* logical partitioning supported */
+#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
+/* ibm,dynamic-reconfiguration-memory property supported */
+#define OV5_DRCONF_MEMORY 0x20
+#define OV5_LARGE_PAGES 0x10 /* large pages supported */
+
+/*
+ * The architecture vector has an array of PVR mask/value pairs,
+ * followed by # option vectors - 1, followed by the option vectors.
+ */
+static unsigned char ibm_architecture_vec[] = {
+ W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
+ W(0xffff0000), W(0x003e0000), /* POWER6 */
+ W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
+ 5 - 1, /* 5 option vectors */
+
+ /* option vector 1: processor architectures supported */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
+ OV1_PPC_2_04 | OV1_PPC_2_05,
+
+ /* option vector 2: Open Firmware options supported */
+ 34 - 1, /* length */
+ OV2_REAL_MODE,
+ 0, 0,
+ W(0xffffffff), /* real_base */
+ W(0xffffffff), /* real_size */
+ W(0xffffffff), /* virt_base */
+ W(0xffffffff), /* virt_size */
+ W(0xffffffff), /* load_base */
+ W(64), /* 128MB min RMA */
+ W(0xffffffff), /* full client load */
+ 0, /* min RMA percentage of total RAM */
+ 48, /* max log_2(hash table size) */
+
+ /* option vector 3: processor options supported */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV3_FP | OV3_VMX,
+
+ /* option vector 4: IBM PAPR implementation */
+ 2 - 1, /* length */
+ 0, /* don't halt */
+
+ /* option vector 5: PAPR/OF options */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
+};
+
+/* Old method - ELF header with PT_NOTE sections */
static struct fake_elf {
Elf32_Ehdr elfhdr;
Elf32_Phdr phdr[2];
@@ -728,8 +814,26 @@ static struct fake_elf {
static void __init prom_send_capabilities(void)
{
- ihandle elfloader;
+ ihandle elfloader, root;
+ prom_arg_t ret;
+
+ root = call_prom("open", 1, 1, ADDR("/"));
+ if (root != 0) {
+ /* try calling the ibm,client-architecture-support method */
+ if (call_prom_ret("call-method", 3, 2, &ret,
+ ADDR("ibm,client-architecture-support"),
+ ADDR(ibm_architecture_vec)) == 0) {
+ /* the call exists... */
+ if (ret)
+ prom_printf("WARNING: ibm,client-architecture"
+ "-support call FAILED!\n");
+ call_prom("close", 1, 0, root);
+ return;
+ }
+ call_prom("close", 1, 0, root);
+ }
+ /* no ibm,client-architecture-support call, try the old way */
elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
if (elfloader == 0) {
prom_printf("couldn't open /packages/elf-loader\n");
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index bcb83574335..4a677d1bd4e 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -538,7 +538,7 @@ void do_syscall_trace_enter(struct pt_regs *regs)
do_syscall_trace();
if (unlikely(current->audit_context))
- audit_syscall_entry(current,
+ audit_syscall_entry(
#ifdef CONFIG_PPC32
AUDIT_ARCH_PPC,
#else
@@ -556,8 +556,7 @@ void do_syscall_trace_leave(struct pt_regs *regs)
#endif
if (unlikely(current->audit_context))
- audit_syscall_exit(current,
- (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+ audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1d93e73a700..684ab1d49c6 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -516,3 +516,11 @@ void probe_machine(void)
printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
}
+
+int check_legacy_ioport(unsigned long base_port)
+{
+ if (ppc_md.check_legacy_ioport == NULL)
+ return 0;
+ return ppc_md.check_legacy_ioport(base_port);
+}
+EXPORT_SYMBOL(check_legacy_ioport);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 13e91c4d70a..4467c49903b 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -594,14 +594,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
printk("[terminate]%04x %s\n", src, msg);
}
-int check_legacy_ioport(unsigned long base_port)
-{
- if (ppc_md.check_legacy_ioport == NULL)
- return 0;
- return ppc_md.check_legacy_ioport(base_port);
-}
-EXPORT_SYMBOL(check_legacy_ioport);
-
void cpu_die(void)
{
if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 73560ef6f80..5bc2585c803 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -279,7 +279,7 @@ static void unregister_cpu_online(unsigned int cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-static int __devinit sysfs_cpu_notify(struct notifier_block *self,
+static int sysfs_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned int)(long)hcpu;
@@ -297,7 +297,7 @@ static int __devinit sysfs_cpu_notify(struct notifier_block *self,
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata sysfs_cpu_nb = {
+static struct notifier_block sysfs_cpu_nb = {
.notifier_call = sysfs_cpu_notify,
};
@@ -322,13 +322,31 @@ static void register_nodes(void)
}
}
}
+
+int sysfs_add_device_to_node(struct sys_device *dev, int nid)
+{
+ struct node *node = &node_devices[nid];
+ return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+}
+
+void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
+{
+ struct node *node = &node_devices[nid];
+ sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
+}
+
#else
static void register_nodes(void)
{
return;
}
+
#endif
+EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
+EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
+
/* Only valid if CPU is present. */
static ssize_t show_physical_id(struct sys_device *dev, char *buf)
{
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index a14c9640384..cf56a1d499f 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -324,3 +324,22 @@ COMPAT_SYS(ppoll)
SYSCALL(unshare)
SYSCALL(splice)
SYSCALL(tee)
+SYSCALL(vmsplice)
+COMPAT_SYS(openat)
+SYSCALL(mkdirat)
+SYSCALL(mknodat)
+SYSCALL(fchownat)
+COMPAT_SYS(futimesat)
+SYSX(sys_newfstatat, sys_fstatat64, sys_fstatat64)
+SYSCALL(unlinkat)
+SYSCALL(renameat)
+SYSCALL(linkat)
+SYSCALL(symlinkat)
+SYSCALL(readlinkat)
+SYSCALL(fchmodat)
+SYSCALL(faccessat)
+
+/*
+ * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c
+ * as well when appropriate.
+ */
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 13c655ba284..971020cf3f7 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -202,7 +202,7 @@ static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
size_t size, enum dma_data_direction direction)
{
return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
- direction);
+ ~0ul, direction);
}
static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
@@ -216,7 +216,7 @@ static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction)
{
return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
- nelems, direction);
+ nelems, ~0ul, direction);
}
static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
@@ -229,7 +229,7 @@ static void *vio_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
- dma_handle, flag);
+ dma_handle, ~0ul, flag);
}
static void vio_free_coherent(struct device *dev, size_t size,