Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: powerpc: Use generic compat_sys_old_readdir powerpc/kexec: Fix up KEXEC_CONTROL_CODE_SIZE missed during conversion powerpc: Remove dead module_find_bug code powerpc: Add CMO enabled flag and paging space data to lparcfg powerpc: Fix CMM page loaning on 64k page kernel with 4k hardware pages powerpc: Make CMO paging space pool ID and page size available powerpc: Fix lockdep IRQ tracing bug powerpc: Fix TLB invalidation on boot on 32-bit powerpc: Fix loss of vdso on fork on 32-bit
This commit is contained in:
commit
04cde035fa
|
@ -291,6 +291,28 @@ struct hvcall_mpp_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
int h_get_mpp(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 /* __ASSEMBLY__ */
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_POWERPC_HVCALL_H */
|
#endif /* _ASM_POWERPC_HVCALL_H */
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#define TRACE_ENABLE_INTS bl .trace_hardirqs_on
|
#define TRACE_ENABLE_INTS bl .trace_hardirqs_on
|
||||||
#define TRACE_DISABLE_INTS bl .trace_hardirqs_off
|
#define TRACE_DISABLE_INTS bl .trace_hardirqs_off
|
||||||
#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
|
#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip) \
|
||||||
cmpdi en, 0; \
|
cmpdi en,0; \
|
||||||
bne 95f; \
|
bne 95f; \
|
||||||
stb en,PACASOFTIRQEN(r13); \
|
stb en,PACASOFTIRQEN(r13); \
|
||||||
bl .trace_hardirqs_off; \
|
bl .trace_hardirqs_off; \
|
||||||
|
@ -29,7 +29,8 @@
|
||||||
li en,1;
|
li en,1;
|
||||||
#define TRACE_AND_RESTORE_IRQ(en) \
|
#define TRACE_AND_RESTORE_IRQ(en) \
|
||||||
TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \
|
TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f); \
|
||||||
96: stb en,PACASOFTIRQEN(r13)
|
stb en,PACASOFTIRQEN(r13); \
|
||||||
|
96:
|
||||||
#else
|
#else
|
||||||
#define TRACE_ENABLE_INTS
|
#define TRACE_ENABLE_INTS
|
||||||
#define TRACE_DISABLE_INTS
|
#define TRACE_DISABLE_INTS
|
||||||
|
|
|
@ -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)
|
static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
mm->context.id = NO_CONTEXT;
|
mm->context.id = NO_CONTEXT;
|
||||||
mm->context.vdso_base = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ COMPAT_SYS_SPU(readlink)
|
||||||
SYSCALL(uselib)
|
SYSCALL(uselib)
|
||||||
SYSCALL(swapon)
|
SYSCALL(swapon)
|
||||||
SYSCALL(reboot)
|
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(mmap)
|
||||||
SYSCALL_SPU(munmap)
|
SYSCALL_SPU(munmap)
|
||||||
SYSCALL_SPU(truncate)
|
SYSCALL_SPU(truncate)
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ flush_tlbs:
|
||||||
lis r10, 0x40
|
lis r10, 0x40
|
||||||
1: addic. r10, r10, -0x1000
|
1: addic. r10, r10, -0x1000
|
||||||
tlbie r10
|
tlbie r10
|
||||||
blt 1b
|
bgt 1b
|
||||||
sync
|
sync
|
||||||
blr
|
blr
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,8 @@ static void pseries_cmo_data(struct seq_file *m)
|
||||||
unsigned long cmo_faults = 0;
|
unsigned long cmo_faults = 0;
|
||||||
unsigned long cmo_fault_time = 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))
|
if (!firmware_has_feature(FW_FEATURE_CMO))
|
||||||
return;
|
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_faults=%lu\n", cmo_faults);
|
||||||
seq_printf(m, "cmo_fault_time_usec=%lu\n",
|
seq_printf(m, "cmo_fault_time_usec=%lu\n",
|
||||||
cmo_fault_time / tb_ticks_per_usec);
|
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)
|
static int pseries_lparcfg_data(struct seq_file *m, void *v)
|
||||||
|
|
|
@ -899,7 +899,7 @@ relocate_new_kernel:
|
||||||
|
|
||||||
/* set a new stack at the bottom of our page... */
|
/* set a new stack at the bottom of our page... */
|
||||||
/* (not really needed now) */
|
/* (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)
|
stw r0, 0(r1)
|
||||||
|
|
||||||
/* Do the copies */
|
/* Do the copies */
|
||||||
|
|
|
@ -99,18 +99,3 @@ void module_arch_cleanup(struct module *mod)
|
||||||
{
|
{
|
||||||
module_bug_cleanup(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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -52,63 +52,6 @@
|
||||||
#include <asm/ppc-pci.h>
|
#include <asm/ppc-pci.h>
|
||||||
#include <asm/syscalls.h>
|
#include <asm/syscalls.h>
|
||||||
|
|
||||||
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,
|
asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
|
||||||
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _PSERIES_PLPAR_WRAPPERS_H
|
#define _PSERIES_PLPAR_WRAPPERS_H
|
||||||
|
|
||||||
#include <asm/hvcall.h>
|
#include <asm/hvcall.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
static inline long poll_pending(void)
|
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)
|
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)
|
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);
|
extern void vpa_init(int cpu);
|
||||||
|
|
|
@ -68,6 +68,9 @@
|
||||||
#include "plpar_wrappers.h"
|
#include "plpar_wrappers.h"
|
||||||
#include "pseries.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 */
|
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;
|
char *ptr, *key, *value, *end;
|
||||||
int call_status;
|
int call_status;
|
||||||
int PrPSP = -1;
|
int page_order = IOMMU_PAGE_SHIFT;
|
||||||
int SecPSP = -1;
|
|
||||||
|
|
||||||
pr_debug(" -> fw_cmo_feature_init()\n");
|
pr_debug(" -> fw_cmo_feature_init()\n");
|
||||||
spin_lock(&rtas_data_buf_lock);
|
spin_lock(&rtas_data_buf_lock);
|
||||||
|
@ -365,21 +367,31 @@ void pSeries_cmo_feature_init(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == strcmp(key, "PrPSP"))
|
if (0 == strcmp(key, "CMOPageSize"))
|
||||||
PrPSP = simple_strtol(value, NULL, 10);
|
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"))
|
else if (0 == strcmp(key, "SecPSP"))
|
||||||
SecPSP = simple_strtol(value, NULL, 10);
|
CMO_SecPSP = simple_strtol(value, NULL, 10);
|
||||||
value = key = ptr + 1;
|
value = key = ptr + 1;
|
||||||
}
|
}
|
||||||
ptr++;
|
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_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;
|
powerpc_firmware_features |= FW_FEATURE_CMO;
|
||||||
} else
|
} 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);
|
spin_unlock(&rtas_data_buf_lock);
|
||||||
pr_debug(" <- fw_cmo_feature_init()\n");
|
pr_debug(" <- fw_cmo_feature_init()\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue