You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'x86/vdso' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next
Pull x86 cdso updates from Peter Anvin: "Vdso cleanups and improvements largely from Andy Lutomirski. This makes the vdso a lot less ''special''" * 'x86/vdso' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/vdso, build: Make LE access macros clearer, host-safe x86/vdso, build: Fix cross-compilation from big-endian architectures x86/vdso, build: When vdso2c fails, unlink the output x86, vdso: Fix an OOPS accessing the HPET mapping w/o an HPET x86, mm: Replace arch_vma_name with vm_ops->name for vsyscalls x86, mm: Improve _install_special_mapping and fix x86 vdso naming mm, fs: Add vm_ops->name as an alternative to arch_vma_name x86, vdso: Fix an OOPS accessing the HPET mapping w/o an HPET x86, vdso: Remove vestiges of VDSO_PRELINK and some outdated comments x86, vdso: Move the vvar and hpet mappings next to the 64-bit vDSO x86, vdso: Move the 32-bit vdso special pages after the text x86, vdso: Reimplement vdso.so preparation in build-time C x86, vdso: Move syscall and sysenter setup into kernel/cpu/common.c x86, vdso: Clean up 32-bit vs 64-bit vdso params x86, mm: Ensure correct alignment of the fixmap
This commit is contained in:
@@ -383,8 +383,8 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
|
||||
} else {
|
||||
/* Return stub is in 32bit vsyscall page */
|
||||
if (current->mm->context.vdso)
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso,
|
||||
sigreturn);
|
||||
restorer = current->mm->context.vdso +
|
||||
selected_vdso32->sym___kernel_sigreturn;
|
||||
else
|
||||
restorer = &frame->retcode;
|
||||
}
|
||||
@@ -462,8 +462,8 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
else
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso,
|
||||
rt_sigreturn);
|
||||
restorer = current->mm->context.vdso +
|
||||
selected_vdso32->sym___kernel_rt_sigreturn;
|
||||
put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
|
||||
|
||||
/*
|
||||
|
||||
+20
-15
@@ -75,7 +75,12 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
|
||||
|
||||
#include <asm/vdso.h>
|
||||
|
||||
extern unsigned int vdso_enabled;
|
||||
#ifdef CONFIG_X86_64
|
||||
extern unsigned int vdso64_enabled;
|
||||
#endif
|
||||
#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
|
||||
extern unsigned int vdso32_enabled;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
@@ -269,9 +274,9 @@ extern int force_personality32;
|
||||
|
||||
struct task_struct;
|
||||
|
||||
#define ARCH_DLINFO_IA32(vdso_enabled) \
|
||||
#define ARCH_DLINFO_IA32 \
|
||||
do { \
|
||||
if (vdso_enabled) { \
|
||||
if (vdso32_enabled) { \
|
||||
NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \
|
||||
} \
|
||||
@@ -281,7 +286,7 @@ do { \
|
||||
|
||||
#define STACK_RND_MASK (0x7ff)
|
||||
|
||||
#define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled)
|
||||
#define ARCH_DLINFO ARCH_DLINFO_IA32
|
||||
|
||||
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
|
||||
|
||||
@@ -292,16 +297,17 @@ do { \
|
||||
|
||||
#define ARCH_DLINFO \
|
||||
do { \
|
||||
if (vdso_enabled) \
|
||||
if (vdso64_enabled) \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
|
||||
(unsigned long)current->mm->context.vdso); \
|
||||
(unsigned long __force)current->mm->context.vdso); \
|
||||
} while (0)
|
||||
|
||||
/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
|
||||
#define ARCH_DLINFO_X32 \
|
||||
do { \
|
||||
if (vdso_enabled) \
|
||||
if (vdso64_enabled) \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
|
||||
(unsigned long)current->mm->context.vdso); \
|
||||
(unsigned long __force)current->mm->context.vdso); \
|
||||
} while (0)
|
||||
|
||||
#define AT_SYSINFO 32
|
||||
@@ -310,7 +316,7 @@ do { \
|
||||
if (test_thread_flag(TIF_X32)) \
|
||||
ARCH_DLINFO_X32; \
|
||||
else \
|
||||
ARCH_DLINFO_IA32(sysctl_vsyscall32)
|
||||
ARCH_DLINFO_IA32
|
||||
|
||||
#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
|
||||
|
||||
@@ -319,18 +325,17 @@ else \
|
||||
#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
|
||||
|
||||
#define VDSO_ENTRY \
|
||||
((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
|
||||
((unsigned long)current->mm->context.vdso + \
|
||||
selected_vdso32->sym___kernel_vsyscall)
|
||||
|
||||
struct linux_binprm;
|
||||
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
|
||||
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp);
|
||||
extern int x32_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp);
|
||||
|
||||
extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
|
||||
#define compat_arch_setup_additional_pages syscall32_setup_pages
|
||||
extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp);
|
||||
#define compat_arch_setup_additional_pages compat_arch_setup_additional_pages
|
||||
|
||||
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define arch_randomize_brk arch_randomize_brk
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <linux/threads.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#else
|
||||
#include <asm/vsyscall.h>
|
||||
#include <uapi/asm/vsyscall.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -41,7 +41,8 @@
|
||||
extern unsigned long __FIXADDR_TOP;
|
||||
#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)
|
||||
#else
|
||||
#define FIXADDR_TOP (VSYSCALL_END-PAGE_SIZE)
|
||||
#define FIXADDR_TOP (round_up(VSYSCALL_ADDR + PAGE_SIZE, 1<<PMD_SHIFT) - \
|
||||
PAGE_SIZE)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -68,11 +69,7 @@ enum fixed_addresses {
|
||||
#ifdef CONFIG_X86_32
|
||||
FIX_HOLE,
|
||||
#else
|
||||
VSYSCALL_LAST_PAGE,
|
||||
VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
|
||||
+ ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
|
||||
VVAR_PAGE,
|
||||
VSYSCALL_HPET,
|
||||
VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
|
||||
#ifdef CONFIG_PARAVIRT_CLOCK
|
||||
PVCLOCK_FIXMAP_BEGIN,
|
||||
PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
struct mutex lock;
|
||||
void *vdso;
|
||||
void __user *vdso;
|
||||
} mm_context_t;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
@@ -12,8 +12,6 @@ void ia32_syscall(void);
|
||||
void ia32_cstar_target(void);
|
||||
void ia32_sysenter_target(void);
|
||||
|
||||
void syscall32_cpu_init(void);
|
||||
|
||||
void x86_configure_nx(void);
|
||||
void x86_report_nx(void);
|
||||
|
||||
|
||||
+34
-46
@@ -3,63 +3,51 @@
|
||||
|
||||
#include <asm/page_types.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#define DEFINE_VDSO_IMAGE(symname, filename) \
|
||||
__PAGE_ALIGNED_DATA ; \
|
||||
.globl symname##_start, symname##_end ; \
|
||||
.align PAGE_SIZE ; \
|
||||
symname##_start: ; \
|
||||
.incbin filename ; \
|
||||
symname##_end: ; \
|
||||
.align PAGE_SIZE /* extra data here leaks to userspace. */ ; \
|
||||
\
|
||||
.previous ; \
|
||||
\
|
||||
.globl symname##_pages ; \
|
||||
.bss ; \
|
||||
.align 8 ; \
|
||||
.type symname##_pages, @object ; \
|
||||
symname##_pages: ; \
|
||||
.zero (symname##_end - symname##_start + PAGE_SIZE - 1) / PAGE_SIZE * (BITS_PER_LONG / 8) ; \
|
||||
.size symname##_pages, .-symname##_pages
|
||||
#include <linux/mm_types.h>
|
||||
|
||||
#else
|
||||
struct vdso_image {
|
||||
void *data;
|
||||
unsigned long size; /* Always a multiple of PAGE_SIZE */
|
||||
|
||||
#define DECLARE_VDSO_IMAGE(symname) \
|
||||
extern char symname##_start[], symname##_end[]; \
|
||||
extern struct page *symname##_pages[]
|
||||
/* text_mapping.pages is big enough for data/size page pointers */
|
||||
struct vm_special_mapping text_mapping;
|
||||
|
||||
unsigned long alt, alt_len;
|
||||
|
||||
unsigned long sym_end_mapping; /* Total size of the mapping */
|
||||
|
||||
unsigned long sym_vvar_page;
|
||||
unsigned long sym_hpet_page;
|
||||
unsigned long sym_VDSO32_NOTE_MASK;
|
||||
unsigned long sym___kernel_sigreturn;
|
||||
unsigned long sym___kernel_rt_sigreturn;
|
||||
unsigned long sym___kernel_vsyscall;
|
||||
unsigned long sym_VDSO32_SYSENTER_RETURN;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
extern const struct vdso_image vdso_image_64;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_X32
|
||||
extern const struct vdso_image vdso_image_x32;
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
|
||||
|
||||
#include <asm/vdso32.h>
|
||||
|
||||
DECLARE_VDSO_IMAGE(vdso32_int80);
|
||||
extern const struct vdso_image vdso_image_32_int80;
|
||||
#ifdef CONFIG_COMPAT
|
||||
DECLARE_VDSO_IMAGE(vdso32_syscall);
|
||||
extern const struct vdso_image vdso_image_32_syscall;
|
||||
#endif
|
||||
DECLARE_VDSO_IMAGE(vdso32_sysenter);
|
||||
extern const struct vdso_image vdso_image_32_sysenter;
|
||||
|
||||
/*
|
||||
* Given a pointer to the vDSO image, find the pointer to VDSO32_name
|
||||
* as that symbol is defined in the vDSO sources or linker script.
|
||||
*/
|
||||
#define VDSO32_SYMBOL(base, name) \
|
||||
({ \
|
||||
extern const char VDSO32_##name[]; \
|
||||
(void __user *)(VDSO32_##name + (unsigned long)(base)); \
|
||||
})
|
||||
extern const struct vdso_image *selected_vdso32;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These symbols are defined with the addresses in the vsyscall page.
|
||||
* See vsyscall-sigreturn.S.
|
||||
*/
|
||||
extern void __user __kernel_sigreturn;
|
||||
extern void __user __kernel_rt_sigreturn;
|
||||
|
||||
void __init patch_vdso32(void *vdso, size_t len);
|
||||
extern void __init init_vdso_image(const struct vdso_image *image);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef _ASM_X86_VDSO32_H
|
||||
#define _ASM_X86_VDSO32_H
|
||||
|
||||
#define VDSO_BASE_PAGE 0
|
||||
#define VDSO_VVAR_PAGE 1
|
||||
#define VDSO_HPET_PAGE 2
|
||||
#define VDSO_PAGES 3
|
||||
#define VDSO_PREV_PAGES 2
|
||||
#define VDSO_OFFSET(x) ((x) * PAGE_SIZE)
|
||||
|
||||
#endif
|
||||
@@ -29,31 +29,13 @@
|
||||
|
||||
#else
|
||||
|
||||
#ifdef BUILD_VDSO32
|
||||
extern char __vvar_page;
|
||||
|
||||
#define DECLARE_VVAR(offset, type, name) \
|
||||
extern type vvar_ ## name __attribute__((visibility("hidden")));
|
||||
|
||||
#define VVAR(name) (vvar_ ## name)
|
||||
|
||||
#else
|
||||
|
||||
extern char __vvar_page;
|
||||
|
||||
/* Base address of vvars. This is not ABI. */
|
||||
#ifdef CONFIG_X86_64
|
||||
#define VVAR_ADDRESS (-10*1024*1024 - 4096)
|
||||
#else
|
||||
#define VVAR_ADDRESS (&__vvar_page)
|
||||
#endif
|
||||
|
||||
#define DECLARE_VVAR(offset, type, name) \
|
||||
static type const * const vvaraddr_ ## name = \
|
||||
(void *)(VVAR_ADDRESS + (offset));
|
||||
|
||||
#define VVAR(name) (*vvaraddr_ ## name)
|
||||
#endif
|
||||
|
||||
#define DEFINE_VVAR(type, name) \
|
||||
type name \
|
||||
__attribute__((section(".vvar_" #name), aligned(16))) __visible
|
||||
|
||||
@@ -7,11 +7,6 @@ enum vsyscall_num {
|
||||
__NR_vgetcpu,
|
||||
};
|
||||
|
||||
#define VSYSCALL_START (-10UL << 20)
|
||||
#define VSYSCALL_SIZE 1024
|
||||
#define VSYSCALL_END (-2UL << 20)
|
||||
#define VSYSCALL_MAPPED_PAGES 1
|
||||
#define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
|
||||
|
||||
#define VSYSCALL_ADDR (-10UL << 20)
|
||||
|
||||
#endif /* _UAPI_ASM_X86_VSYSCALL_H */
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/debugreg.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/vsyscall.h>
|
||||
#include <linux/topology.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -953,6 +954,38 @@ static void vgetcpu_set_mode(void)
|
||||
else
|
||||
vgetcpu_mode = VGETCPU_LSL;
|
||||
}
|
||||
|
||||
/* May not be __init: called during resume */
|
||||
static void syscall32_cpu_init(void)
|
||||
{
|
||||
/* Load these always in case some future AMD CPU supports
|
||||
SYSENTER from compat mode too. */
|
||||
wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
|
||||
wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL);
|
||||
wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
|
||||
|
||||
wrmsrl(MSR_CSTAR, ia32_cstar_target);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
void enable_sep_cpu(void)
|
||||
{
|
||||
int cpu = get_cpu();
|
||||
struct tss_struct *tss = &per_cpu(init_tss, cpu);
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_SEP)) {
|
||||
put_cpu();
|
||||
return;
|
||||
}
|
||||
|
||||
tss->x86_tss.ss1 = __KERNEL_CS;
|
||||
tss->x86_tss.sp1 = sizeof(struct tss_struct) + (unsigned long) tss;
|
||||
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
|
||||
wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0);
|
||||
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0);
|
||||
put_cpu();
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init identify_boot_cpu(void)
|
||||
|
||||
@@ -74,9 +74,6 @@ static inline void hpet_writel(unsigned int d, unsigned int a)
|
||||
static inline void hpet_set_mapping(void)
|
||||
{
|
||||
hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
|
||||
#ifdef CONFIG_X86_64
|
||||
__set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VVAR_NOCACHE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void hpet_clear_mapping(void)
|
||||
|
||||
@@ -298,7 +298,8 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
|
||||
}
|
||||
|
||||
if (current->mm->context.vdso)
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
|
||||
restorer = current->mm->context.vdso +
|
||||
selected_vdso32->sym___kernel_sigreturn;
|
||||
else
|
||||
restorer = &frame->retcode;
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
@@ -361,7 +362,8 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
|
||||
restorer = current->mm->context.vdso +
|
||||
selected_vdso32->sym___kernel_sigreturn;
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
put_user_ex(restorer, &frame->pretcode);
|
||||
|
||||
@@ -91,7 +91,7 @@ static int addr_to_vsyscall_nr(unsigned long addr)
|
||||
{
|
||||
int nr;
|
||||
|
||||
if ((addr & ~0xC00UL) != VSYSCALL_START)
|
||||
if ((addr & ~0xC00UL) != VSYSCALL_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
nr = (addr & 0xC00UL) >> 10;
|
||||
@@ -330,24 +330,17 @@ void __init map_vsyscall(void)
|
||||
{
|
||||
extern char __vsyscall_page;
|
||||
unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
|
||||
unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page);
|
||||
|
||||
__set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall,
|
||||
__set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
|
||||
vsyscall_mode == NATIVE
|
||||
? PAGE_KERNEL_VSYSCALL
|
||||
: PAGE_KERNEL_VVAR);
|
||||
BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_FIRST_PAGE) !=
|
||||
(unsigned long)VSYSCALL_START);
|
||||
|
||||
__set_fixmap(VVAR_PAGE, physaddr_vvar_page, PAGE_KERNEL_VVAR);
|
||||
BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) !=
|
||||
(unsigned long)VVAR_ADDRESS);
|
||||
BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
|
||||
(unsigned long)VSYSCALL_ADDR);
|
||||
}
|
||||
|
||||
static int __init vsyscall_init(void)
|
||||
{
|
||||
BUG_ON(VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE));
|
||||
|
||||
cpu_notifier_register_begin();
|
||||
|
||||
on_each_cpu(cpu_vsyscall_init, NULL, 1);
|
||||
|
||||
+3
-2
@@ -18,7 +18,8 @@
|
||||
#include <asm/traps.h> /* dotraplinkage, ... */
|
||||
#include <asm/pgalloc.h> /* pgd_*(), ... */
|
||||
#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
|
||||
#include <asm/fixmap.h> /* VSYSCALL_START */
|
||||
#include <asm/fixmap.h> /* VSYSCALL_ADDR */
|
||||
#include <asm/vsyscall.h> /* emulate_vsyscall */
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <asm/trace/exceptions.h>
|
||||
@@ -771,7 +772,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
|
||||
* emulation.
|
||||
*/
|
||||
if (unlikely((error_code & PF_INSTR) &&
|
||||
((address & ~0xfff) == VSYSCALL_START))) {
|
||||
((address & ~0xfff) == VSYSCALL_ADDR))) {
|
||||
if (emulate_vsyscall(regs, address))
|
||||
return;
|
||||
}
|
||||
|
||||
+14
-15
@@ -1055,8 +1055,8 @@ void __init mem_init(void)
|
||||
after_bootmem = 1;
|
||||
|
||||
/* Register memory areas for /proc/kcore */
|
||||
kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
|
||||
VSYSCALL_END - VSYSCALL_START, KCORE_OTHER);
|
||||
kclist_add(&kcore_vsyscall, (void *)VSYSCALL_ADDR,
|
||||
PAGE_SIZE, KCORE_OTHER);
|
||||
|
||||
mem_init_print_info(NULL);
|
||||
}
|
||||
@@ -1185,11 +1185,19 @@ int kern_addr_valid(unsigned long addr)
|
||||
* covers the 64bit vsyscall page now. 32bit has a real VMA now and does
|
||||
* not need special handling anymore:
|
||||
*/
|
||||
static const char *gate_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
return "[vsyscall]";
|
||||
}
|
||||
static struct vm_operations_struct gate_vma_ops = {
|
||||
.name = gate_vma_name,
|
||||
};
|
||||
static struct vm_area_struct gate_vma = {
|
||||
.vm_start = VSYSCALL_START,
|
||||
.vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
|
||||
.vm_start = VSYSCALL_ADDR,
|
||||
.vm_end = VSYSCALL_ADDR + PAGE_SIZE,
|
||||
.vm_page_prot = PAGE_READONLY_EXEC,
|
||||
.vm_flags = VM_READ | VM_EXEC
|
||||
.vm_flags = VM_READ | VM_EXEC,
|
||||
.vm_ops = &gate_vma_ops,
|
||||
};
|
||||
|
||||
struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
|
||||
@@ -1218,16 +1226,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)
|
||||
*/
|
||||
int in_gate_area_no_mm(unsigned long addr)
|
||||
{
|
||||
return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
|
||||
}
|
||||
|
||||
const char *arch_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
|
||||
return "[vdso]";
|
||||
if (vma == &gate_vma)
|
||||
return "[vsyscall]";
|
||||
return NULL;
|
||||
return (addr & PAGE_MASK) == VSYSCALL_ADDR;
|
||||
}
|
||||
|
||||
static unsigned long probe_memory_block_size(void)
|
||||
|
||||
@@ -367,6 +367,12 @@ void __init early_ioremap_init(void)
|
||||
{
|
||||
pmd_t *pmd;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
BUILD_BUG_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
|
||||
#else
|
||||
WARN_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
|
||||
#endif
|
||||
|
||||
early_ioremap_setup();
|
||||
|
||||
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
|
||||
|
||||
@@ -456,9 +456,9 @@ void __init reserve_top_address(unsigned long reserve)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
BUG_ON(fixmaps_set > 0);
|
||||
printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
|
||||
(int)-reserve);
|
||||
__FIXADDR_TOP = -reserve - PAGE_SIZE;
|
||||
__FIXADDR_TOP = round_down(-reserve, 1 << PMD_SHIFT) - PAGE_SIZE;
|
||||
printk(KERN_INFO "Reserving virtual address space above 0x%08lx (rounded to 0x%08lx)\n",
|
||||
-reserve, __FIXADDR_TOP + PAGE_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
unsigned int __read_mostly vdso_enabled = 1;
|
||||
static unsigned int __read_mostly vdso_enabled = 1;
|
||||
unsigned long um_vdso_addr;
|
||||
|
||||
extern unsigned long task_size;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
vdso.lds
|
||||
vdso-syms.lds
|
||||
vdsox32.lds
|
||||
vdsox32-syms.lds
|
||||
vdso32-syms.lds
|
||||
vdso32-syscall-syms.lds
|
||||
vdso32-sysenter-syms.lds
|
||||
vdso32-int80-syms.lds
|
||||
vdso-image-*.c
|
||||
vdso2c
|
||||
|
||||
+32
-58
@@ -24,15 +24,30 @@ vobj64s := $(filter-out $(vobjx32s-compat),$(vobjs-y))
|
||||
|
||||
# files to link into kernel
|
||||
obj-y += vma.o
|
||||
obj-$(VDSO64-y) += vdso.o
|
||||
obj-$(VDSOX32-y) += vdsox32.o
|
||||
obj-$(VDSO32-y) += vdso32.o vdso32-setup.o
|
||||
|
||||
# vDSO images to build
|
||||
vdso_img-$(VDSO64-y) += 64
|
||||
vdso_img-$(VDSOX32-y) += x32
|
||||
vdso_img-$(VDSO32-y) += 32-int80
|
||||
vdso_img-$(CONFIG_COMPAT) += 32-syscall
|
||||
vdso_img-$(VDSO32-y) += 32-sysenter
|
||||
|
||||
obj-$(VDSO32-y) += vdso32-setup.o
|
||||
|
||||
vobjs := $(foreach F,$(vobj64s),$(obj)/$F)
|
||||
|
||||
$(obj)/vdso.o: $(obj)/vdso.so
|
||||
|
||||
targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
|
||||
targets += vdso.lds $(vobjs-y)
|
||||
|
||||
# Build the vDSO image C files and link them in.
|
||||
vdso_img_objs := $(vdso_img-y:%=vdso-image-%.o)
|
||||
vdso_img_cfiles := $(vdso_img-y:%=vdso-image-%.c)
|
||||
vdso_img_sodbg := $(vdso_img-y:%=vdso%.so.dbg)
|
||||
obj-y += $(vdso_img_objs)
|
||||
targets += $(vdso_img_cfiles)
|
||||
targets += $(vdso_img_sodbg)
|
||||
.SECONDARY: $(vdso_img-y:%=$(obj)/vdso-image-%.c)
|
||||
|
||||
export CPPFLAGS_vdso.lds += -P -C
|
||||
|
||||
@@ -41,14 +56,18 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
|
||||
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \
|
||||
$(DISABLE_LTO)
|
||||
|
||||
$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
|
||||
|
||||
$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
|
||||
$(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
|
||||
$(call if_changed,vdso)
|
||||
|
||||
$(obj)/%.so: OBJCOPYFLAGS := -S
|
||||
$(obj)/%.so: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,objcopy)
|
||||
hostprogs-y += vdso2c
|
||||
|
||||
quiet_cmd_vdso2c = VDSO2C $@
|
||||
define cmd_vdso2c
|
||||
$(obj)/vdso2c $< $@
|
||||
endef
|
||||
|
||||
$(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso2c FORCE
|
||||
$(call if_changed,vdso2c)
|
||||
|
||||
#
|
||||
# Don't omit frame pointers for ease of userspace debugging, but do
|
||||
@@ -68,22 +87,6 @@ CFLAGS_REMOVE_vclock_gettime.o = -pg
|
||||
CFLAGS_REMOVE_vgetcpu.o = -pg
|
||||
CFLAGS_REMOVE_vvar.o = -pg
|
||||
|
||||
targets += vdso-syms.lds
|
||||
obj-$(VDSO64-y) += vdso-syms.lds
|
||||
|
||||
#
|
||||
# Match symbols in the DSO that look like VDSO*; produce a file of constants.
|
||||
#
|
||||
sed-vdsosym := -e 's/^00*/0/' \
|
||||
-e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p'
|
||||
quiet_cmd_vdsosym = VDSOSYM $@
|
||||
define cmd_vdsosym
|
||||
$(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
|
||||
endef
|
||||
|
||||
$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,vdsosym)
|
||||
|
||||
#
|
||||
# X32 processes use x32 vDSO to access 64bit kernel data.
|
||||
#
|
||||
@@ -94,9 +97,6 @@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
|
||||
# so that it can reach 64bit address space with 64bit pointers.
|
||||
#
|
||||
|
||||
targets += vdsox32-syms.lds
|
||||
obj-$(VDSOX32-y) += vdsox32-syms.lds
|
||||
|
||||
CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds)
|
||||
VDSO_LDFLAGS_vdsox32.lds = -Wl,-m,elf32_x86_64 \
|
||||
-Wl,-soname=linux-vdso.so.1 \
|
||||
@@ -113,9 +113,7 @@ quiet_cmd_x32 = X32 $@
|
||||
$(obj)/%-x32.o: $(obj)/%.o FORCE
|
||||
$(call if_changed,x32)
|
||||
|
||||
targets += vdsox32.so vdsox32.so.dbg vdsox32.lds $(vobjx32s-y)
|
||||
|
||||
$(obj)/vdsox32.o: $(src)/vdsox32.S $(obj)/vdsox32.so
|
||||
targets += vdsox32.lds $(vobjx32s-y)
|
||||
|
||||
$(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
|
||||
$(call if_changed,vdso)
|
||||
@@ -123,7 +121,6 @@ $(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
|
||||
#
|
||||
# Build multiple 32-bit vDSO images to choose from at boot time.
|
||||
#
|
||||
obj-$(VDSO32-y) += vdso32-syms.lds
|
||||
vdso32.so-$(VDSO32-y) += int80
|
||||
vdso32.so-$(CONFIG_COMPAT) += syscall
|
||||
vdso32.so-$(VDSO32-y) += sysenter
|
||||
@@ -138,10 +135,8 @@ VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
|
||||
override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
|
||||
|
||||
targets += vdso32/vdso32.lds
|
||||
targets += $(vdso32-images) $(vdso32-images:=.dbg)
|
||||
targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o)
|
||||
|
||||
extra-y += $(vdso32-images)
|
||||
targets += vdso32/vclock_gettime.o
|
||||
|
||||
$(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%)
|
||||
|
||||
@@ -166,27 +161,6 @@ $(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
|
||||
$(obj)/vdso32/%.o
|
||||
$(call if_changed,vdso)
|
||||
|
||||
# Make vdso32-*-syms.lds from each image, and then make sure they match.
|
||||
# The only difference should be that some do not define VDSO32_SYSENTER_RETURN.
|
||||
|
||||
targets += vdso32-syms.lds $(vdso32.so-y:%=vdso32-%-syms.lds)
|
||||
|
||||
quiet_cmd_vdso32sym = VDSOSYM $@
|
||||
define cmd_vdso32sym
|
||||
if LC_ALL=C sort -u $(filter-out FORCE,$^) > $(@D)/.tmp_$(@F) && \
|
||||
$(foreach H,$(filter-out FORCE,$^),\
|
||||
if grep -q VDSO32_SYSENTER_RETURN $H; \
|
||||
then diff -u $(@D)/.tmp_$(@F) $H; \
|
||||
else sed /VDSO32_SYSENTER_RETURN/d $(@D)/.tmp_$(@F) | \
|
||||
diff -u - $H; fi &&) : ;\
|
||||
then mv -f $(@D)/.tmp_$(@F) $@; \
|
||||
else rm -f $(@D)/.tmp_$(@F); exit 1; \
|
||||
fi
|
||||
endef
|
||||
|
||||
$(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
|
||||
$(call if_changed,vdso32sym)
|
||||
|
||||
#
|
||||
# The DSO images are built using a special linker script.
|
||||
#
|
||||
@@ -197,7 +171,7 @@ quiet_cmd_vdso = VDSO $@
|
||||
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
||||
|
||||
VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
|
||||
$(LTO_CFLAGS)
|
||||
-Wl,-Bsymbolic $(LTO_CFLAGS)
|
||||
GCOV_PROFILE := n
|
||||
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user