diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index fbe2932fa9e9..6251a4b10be7 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -291,6 +291,28 @@ struct hvcall_mpp_data { }; int h_get_mpp(struct hvcall_mpp_data *); + +#ifdef CONFIG_PPC_PSERIES +extern int CMO_PrPSP; +extern int CMO_SecPSP; +extern unsigned long CMO_PageSize; + +static inline int cmo_get_primary_psp(void) +{ + return CMO_PrPSP; +} + +static inline int cmo_get_secondary_psp(void) +{ + return CMO_SecPSP; +} + +static inline unsigned long cmo_get_page_size(void) +{ + return CMO_PageSize; +} +#endif /* CONFIG_PPC_PSERIES */ + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h index 17ba3a881bfd..5f68ecfdf516 100644 --- a/arch/powerpc/include/asm/irqflags.h +++ b/arch/powerpc/include/asm/irqflags.h @@ -20,7 +20,7 @@ #define TRACE_ENABLE_INTS bl .trace_hardirqs_on #define TRACE_DISABLE_INTS bl .trace_hardirqs_off #define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \ - cmpdi en, 0; \ + cmpdi en,0; \ bne 95f; \ stb en,PACASOFTIRQEN(r13); \ bl .trace_hardirqs_off; \ @@ -29,7 +29,8 @@ li en,1; #define TRACE_AND_RESTORE_IRQ(en) \ TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \ -96: stb en,PACASOFTIRQEN(r13) + stb en,PACASOFTIRQEN(r13); \ +96: #else #define TRACE_ENABLE_INTS #define TRACE_DISABLE_INTS diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 9102b8bf0ead..6b993ef452ff 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -147,7 +147,6 @@ static inline void get_mmu_context(struct mm_struct *mm) static inline int init_new_context(struct task_struct *t, struct mm_struct *mm) { mm->context.id = NO_CONTEXT; - mm->context.vdso_base = 0; return 0; } diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index e084272ed1c2..f6cc7a43b4fa 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -92,7 +92,7 @@ COMPAT_SYS_SPU(readlink) SYSCALL(uselib) SYSCALL(swapon) SYSCALL(reboot) -SYSX(sys_ni_syscall,old32_readdir,old_readdir) +SYSX(sys_ni_syscall,compat_sys_old_readdir,old_readdir) SYSCALL_SPU(mmap) SYSCALL_SPU(munmap) SYSCALL_SPU(truncate) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 99ee2f0f0f2b..8bb657519299 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -1155,7 +1155,7 @@ flush_tlbs: lis r10, 0x40 1: addic. r10, r10, -0x1000 tlbie r10 - blt 1b + bgt 1b sync blr diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 1a09719c7628..b3eef30b5131 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -416,6 +416,8 @@ static void pseries_cmo_data(struct seq_file *m) unsigned long cmo_faults = 0; unsigned long cmo_fault_time = 0; + seq_printf(m, "cmo_enabled=%d\n", firmware_has_feature(FW_FEATURE_CMO)); + if (!firmware_has_feature(FW_FEATURE_CMO)) return; @@ -427,6 +429,9 @@ static void pseries_cmo_data(struct seq_file *m) seq_printf(m, "cmo_faults=%lu\n", cmo_faults); seq_printf(m, "cmo_fault_time_usec=%lu\n", cmo_fault_time / tb_ticks_per_usec); + seq_printf(m, "cmo_primary_psp=%d\n", cmo_get_primary_psp()); + seq_printf(m, "cmo_secondary_psp=%d\n", cmo_get_secondary_psp()); + seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size()); } static int pseries_lparcfg_data(struct seq_file *m, void *v) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 6321ae36f729..7a6dfbca7682 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -899,7 +899,7 @@ relocate_new_kernel: /* set a new stack at the bottom of our page... */ /* (not really needed now) */ - addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */ + addi r1, r4, KEXEC_CONTROL_PAGE_SIZE - 8 /* for LR Save+Back Chain */ stw r0, 0(r1) /* Do the copies */ diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index af07003573c4..7ff292475269 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -99,18 +99,3 @@ void module_arch_cleanup(struct module *mod) { module_bug_cleanup(mod); } - -struct bug_entry *module_find_bug(unsigned long bugaddr) -{ - struct mod_arch_specific *mod; - unsigned int i; - struct bug_entry *bug; - - list_for_each_entry(mod, &module_bug_list, bug_list) { - bug = mod->bug_table; - for (i = 0; i < mod->num_bugs; ++i, ++bug) - if (bugaddr == bug->bug_addr) - return bug; - } - return NULL; -} diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 709f8cb8bfca..d98634c76060 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -52,63 +52,6 @@ #include #include -struct old_linux_dirent32 { - u32 d_ino; - u32 d_offset; - unsigned short d_namlen; - char d_name[1]; -}; - -struct readdir_callback32 { - struct old_linux_dirent32 __user * dirent; - int count; -}; - -static int fillonedir(void * __buf, const char * name, int namlen, - off_t offset, u64 ino, unsigned int d_type) -{ - struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; - struct old_linux_dirent32 __user * dirent; - ino_t d_ino; - - if (buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - buf->count++; - dirent = buf->dirent; - put_user(d_ino, &dirent->d_ino); - put_user(offset, &dirent->d_offset); - put_user(namlen, &dirent->d_namlen); - copy_to_user(dirent->d_name, name, namlen); - put_user(0, dirent->d_name + namlen); - return 0; -} - -asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count) -{ - int error = -EBADF; - struct file * file; - struct readdir_callback32 buf; - - file = fget(fd); - if (!file) - goto out; - - buf.count = 0; - buf.dirent = dirent; - - error = vfs_readdir(file, (filldir_t)fillonedir, &buf); - if (error < 0) - goto out_putf; - error = buf.count; - -out_putf: - fput(file); -out: - return error; -} asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index a437267c6bf8..d967c1893ab5 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -2,6 +2,7 @@ #define _PSERIES_PLPAR_WRAPPERS_H #include +#include static inline long poll_pending(void) { @@ -44,12 +45,34 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) static inline long plpar_page_set_loaned(unsigned long vpa) { - return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa, 0); + unsigned long cmo_page_sz = cmo_get_page_size(); + long rc = 0; + int i; + + for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz) + rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0); + + for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz) + plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, + vpa + i - cmo_page_sz, 0); + + return rc; } static inline long plpar_page_set_active(unsigned long vpa) { - return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa, 0); + unsigned long cmo_page_sz = cmo_get_page_size(); + long rc = 0; + int i; + + for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz) + rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0); + + for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz) + plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, + vpa + i - cmo_page_sz, 0); + + return rc; } extern void vpa_init(int cpu); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 063a0d2fba30..3ce8a139b85d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -68,6 +68,9 @@ #include "plpar_wrappers.h" #include "pseries.h" +int CMO_PrPSP = -1; +int CMO_SecPSP = -1; +unsigned long CMO_PageSize = (ASM_CONST(1) << IOMMU_PAGE_SHIFT); int fwnmi_active; /* TRUE if an FWNMI handler is present */ @@ -325,8 +328,7 @@ void pSeries_cmo_feature_init(void) { char *ptr, *key, *value, *end; int call_status; - int PrPSP = -1; - int SecPSP = -1; + int page_order = IOMMU_PAGE_SHIFT; pr_debug(" -> fw_cmo_feature_init()\n"); spin_lock(&rtas_data_buf_lock); @@ -365,21 +367,31 @@ void pSeries_cmo_feature_init(void) break; } - if (0 == strcmp(key, "PrPSP")) - PrPSP = simple_strtol(value, NULL, 10); + if (0 == strcmp(key, "CMOPageSize")) + page_order = simple_strtol(value, NULL, 10); + else if (0 == strcmp(key, "PrPSP")) + CMO_PrPSP = simple_strtol(value, NULL, 10); else if (0 == strcmp(key, "SecPSP")) - SecPSP = simple_strtol(value, NULL, 10); + CMO_SecPSP = simple_strtol(value, NULL, 10); value = key = ptr + 1; } ptr++; } - if (PrPSP != -1 || SecPSP != -1) { + /* Page size is returned as the power of 2 of the page size, + * convert to the page size in bytes before returning + */ + CMO_PageSize = 1 << page_order; + pr_debug("CMO_PageSize = %lu\n", CMO_PageSize); + + if (CMO_PrPSP != -1 || CMO_SecPSP != -1) { pr_info("CMO enabled\n"); - pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); powerpc_firmware_features |= FW_FEATURE_CMO; } else - pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); + pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, + CMO_SecPSP); spin_unlock(&rtas_data_buf_lock); pr_debug(" <- fw_cmo_feature_init()\n"); }