mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
Merge branch 'parisc-4.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fixes from Helge Deller:
"Since commit 0de798584b
("parisc: Use generic extable search and
sort routines") module loading is boken on parisc, because the parisc
module loader wasn't prepared for the new R_PARISC_PCREL32 relocations.
In addition, due to that breakage, Mikulas Patocka noticed that
handling exceptions from modules probably never worked on parisc. It
was just masked by the fact that exceptions from modules don't happen
during normal use.
This patch series fixes those issues and survives the tests of the
lib/test_user_copy kernel module test. Some patches are tagged for
stable"
* 'parisc-4.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Update comment regarding relative extable support
parisc: Unbreak handling exceptions from kernel modules
parisc: Fix kernel crash with reversed copy_from_user()
parisc: Avoid function pointers for kernel exception routines
parisc: Handle R_PARISC_PCREL32 relocations in kernel modules
This commit is contained in:
commit
5b5b7fd185
@ -44,20 +44,18 @@ static inline long access_ok(int type, const void __user * addr,
|
||||
#define LDD_USER(ptr) BUILD_BUG()
|
||||
#define STD_KERNEL(x, ptr) __put_kernel_asm64(x, ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm64(x, ptr)
|
||||
#define ASM_WORD_INSN ".word\t"
|
||||
#else
|
||||
#define LDD_KERNEL(ptr) __get_kernel_asm("ldd", ptr)
|
||||
#define LDD_USER(ptr) __get_user_asm("ldd", ptr)
|
||||
#define STD_KERNEL(x, ptr) __put_kernel_asm("std", x, ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm("std", x, ptr)
|
||||
#define ASM_WORD_INSN ".dword\t"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The exception table contains two values: the first is an address
|
||||
* for an instruction that is allowed to fault, and the second is
|
||||
* the address to the fixup routine. Even on a 64bit kernel we could
|
||||
* use a 32bit (unsigned int) address here.
|
||||
* The exception table contains two values: the first is the relative offset to
|
||||
* the address of the instruction that is allowed to fault, and the second is
|
||||
* the relative offset to the address of the fixup routine. Since relative
|
||||
* addresses are used, 32bit values are sufficient even on 64bit kernel.
|
||||
*/
|
||||
|
||||
#define ARCH_HAS_RELATIVE_EXTABLE
|
||||
@ -77,6 +75,7 @@ struct exception_table_entry {
|
||||
*/
|
||||
struct exception_data {
|
||||
unsigned long fault_ip;
|
||||
unsigned long fault_gp;
|
||||
unsigned long fault_space;
|
||||
unsigned long fault_addr;
|
||||
};
|
||||
|
@ -299,6 +299,7 @@ int main(void)
|
||||
#endif
|
||||
BLANK();
|
||||
DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
|
||||
DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
|
||||
DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
|
||||
DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
|
||||
BLANK();
|
||||
|
@ -660,6 +660,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
}
|
||||
*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
|
||||
break;
|
||||
case R_PARISC_PCREL32:
|
||||
/* 32-bit PC relative address */
|
||||
*loc = val - dot - 8 + addend;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
|
||||
@ -788,6 +792,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
CHECK_RELOC(val, 22);
|
||||
*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
|
||||
break;
|
||||
case R_PARISC_PCREL32:
|
||||
/* 32-bit PC relative address */
|
||||
*loc = val - dot - 8 + addend;
|
||||
break;
|
||||
case R_PARISC_DIR64:
|
||||
/* 64-bit effective address */
|
||||
*loc64 = val + addend;
|
||||
|
@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64);
|
||||
EXPORT_SYMBOL(lclear_user);
|
||||
EXPORT_SYMBOL(lstrnlen_user);
|
||||
|
||||
/* Global fixups */
|
||||
extern void fixup_get_user_skip_1(void);
|
||||
extern void fixup_get_user_skip_2(void);
|
||||
extern void fixup_put_user_skip_1(void);
|
||||
extern void fixup_put_user_skip_2(void);
|
||||
/* Global fixups - defined as int to avoid creation of function pointers */
|
||||
extern int fixup_get_user_skip_1;
|
||||
extern int fixup_get_user_skip_2;
|
||||
extern int fixup_put_user_skip_1;
|
||||
extern int fixup_put_user_skip_2;
|
||||
EXPORT_SYMBOL(fixup_get_user_skip_1);
|
||||
EXPORT_SYMBOL(fixup_get_user_skip_2);
|
||||
EXPORT_SYMBOL(fixup_put_user_skip_1);
|
||||
|
@ -795,6 +795,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
|
||||
|
||||
if (fault_space == 0 && !faulthandler_disabled())
|
||||
{
|
||||
/* Clean up and return if in exception table. */
|
||||
if (fixup_exception(regs))
|
||||
return;
|
||||
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
|
||||
parisc_terminate("Kernel Fault", regs, code, fault_address);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
.macro get_fault_ip t1 t2
|
||||
loadgp
|
||||
addil LT%__per_cpu_offset,%r27
|
||||
LDREG RT%__per_cpu_offset(%r1),\t1
|
||||
/* t2 = smp_processor_id() */
|
||||
@ -40,14 +41,19 @@
|
||||
LDREG RT%exception_data(%r1),\t1
|
||||
/* t1 = this_cpu_ptr(&exception_data) */
|
||||
add,l \t1,\t2,\t1
|
||||
/* %r27 = t1->fault_gp - restore gp */
|
||||
LDREG EXCDATA_GP(\t1), %r27
|
||||
/* t1 = t1->fault_ip */
|
||||
LDREG EXCDATA_IP(\t1), \t1
|
||||
.endm
|
||||
#else
|
||||
.macro get_fault_ip t1 t2
|
||||
loadgp
|
||||
/* t1 = this_cpu_ptr(&exception_data) */
|
||||
addil LT%exception_data,%r27
|
||||
LDREG RT%exception_data(%r1),\t2
|
||||
/* %r27 = t2->fault_gp - restore gp */
|
||||
LDREG EXCDATA_GP(\t2), %r27
|
||||
/* t1 = t2->fault_ip */
|
||||
LDREG EXCDATA_IP(\t2), \t1
|
||||
.endm
|
||||
|
@ -145,6 +145,7 @@ int fixup_exception(struct pt_regs *regs)
|
||||
struct exception_data *d;
|
||||
d = this_cpu_ptr(&exception_data);
|
||||
d->fault_ip = regs->iaoq[0];
|
||||
d->fault_gp = regs->gr[27];
|
||||
d->fault_space = regs->isr;
|
||||
d->fault_addr = regs->ior;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user