Commit 4bc06c59 authored by Michael Ellerman's avatar Michael Ellerman
Browse files

Merge branch 'topic/func-desc-lkdtm' into next

Merge a topic branch we are maintaining with some cross-architecture
changes to function descriptor handling and their use in LKDTM.

From Christophe's cover letter:

Fix LKDTM for PPC64/IA64/PARISC

PPC64/IA64/PARISC have function descriptors. LKDTM doesn't work on those
three architectures because LKDTM messes up function descriptors with
functions.

This series does some cleanup in the three architectures and refactors
function descriptors so that it can then easily use it in a generic way
in LKDTM.
parents 8219d31e 5e5a6c54
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -205,6 +205,9 @@ config HAVE_FUNCTION_ERROR_INJECTION
config HAVE_NMI
	bool

config HAVE_FUNCTION_DESCRIPTORS
	bool

config TRACE_IRQFLAGS_SUPPORT
	bool

+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ config IA64
	select HAVE_SETUP_PER_CPU_AREA
	select TTY
	select HAVE_ARCH_TRACEHOOK
	select HAVE_FUNCTION_DESCRIPTORS
	select HAVE_VIRT_CPU_ACCOUNTING
	select HUGETLB_PAGE_SIZE_VARIABLE if HUGETLB_PAGE
	select VIRT_TO_BUS
+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ struct got_entry {
 * Layout of the Function Descriptor
 */
struct fdesc {
	uint64_t ip;
	uint64_t addr;
	uint64_t gp;
};

+3 −21
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@

#include <linux/elf.h>
#include <linux/uaccess.h>

typedef struct fdesc func_desc_t;

#include <asm-generic/sections.h>

extern char __phys_per_cpu_start[];
@@ -27,25 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
extern char __start_unwind[], __end_unwind[];
extern char __start_ivt_text[], __end_ivt_text[];

#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1

#undef dereference_function_descriptor
static inline void *dereference_function_descriptor(void *ptr)
{
	struct fdesc *desc = ptr;
	void *p;

	if (!get_kernel_nofault(p, (void *)&desc->ip))
		ptr = p;
	return ptr;
}

#undef dereference_kernel_function_descriptor
static inline void *dereference_kernel_function_descriptor(void *ptr)
{
	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
		return ptr;
	return dereference_function_descriptor(ptr);
}

#endif /* _ASM_IA64_SECTIONS_H */
+3 −3
Original line number Diff line number Diff line
@@ -602,15 +602,15 @@ get_fdesc (struct module *mod, uint64_t value, int *okp)
		return value;

	/* Look for existing function descriptor. */
	while (fdesc->ip) {
		if (fdesc->ip == value)
	while (fdesc->addr) {
		if (fdesc->addr == value)
			return (uint64_t)fdesc;
		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
			BUG();
	}

	/* Create new one */
	fdesc->ip = value;
	fdesc->addr = value;
	fdesc->gp = mod->arch.gp;
	return (uint64_t) fdesc;
}
Loading