mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 07:34:12 +08:00
Merge branch 'topic/vdso' into next
Merge VDSO changes we're keeping in a topic branch, in case they conflict with other VDSO changes in flight.
This commit is contained in:
commit
0882db7f92
@ -25,6 +25,7 @@ int vdso_getcpu_init(void);
|
||||
#ifdef __VDSO64__
|
||||
#define V_FUNCTION_BEGIN(name) \
|
||||
.globl name; \
|
||||
.type name,@function; \
|
||||
name: \
|
||||
|
||||
#define V_FUNCTION_END(name) \
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/vdso_datapage.h>
|
||||
|
||||
static __always_inline int do_syscall_3(const unsigned long _r0, const unsigned long _r3,
|
||||
const unsigned long _r4, const unsigned long _r5)
|
||||
{
|
||||
@ -43,11 +45,21 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig
|
||||
|
||||
static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
|
||||
{
|
||||
return NULL;
|
||||
struct vdso_arch_data *data;
|
||||
|
||||
asm (
|
||||
" bcl 20, 31, .+4 ;"
|
||||
"0: mflr %0 ;"
|
||||
" addis %0, %0, (_vdso_datapage - 0b)@ha ;"
|
||||
" addi %0, %0, (_vdso_datapage - 0b)@l ;"
|
||||
: "=r" (data) : : "lr"
|
||||
);
|
||||
|
||||
return &data->rng_data;
|
||||
}
|
||||
|
||||
ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
|
||||
size_t opaque_len, const struct vdso_rng_data *vd);
|
||||
size_t opaque_len);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
|
@ -82,8 +82,9 @@ struct vdso_arch_data {
|
||||
__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
|
||||
__u32 compat_syscall_map[SYSCALL_MAP_SIZE]; /* Map of compat syscalls */
|
||||
|
||||
struct vdso_data data[CS_BASES];
|
||||
struct vdso_rng_data rng_data;
|
||||
|
||||
struct vdso_data data[CS_BASES] __aligned(1 << CONFIG_PAGE_SHIFT);
|
||||
};
|
||||
|
||||
#else /* CONFIG_PPC64 */
|
||||
@ -95,8 +96,9 @@ struct vdso_arch_data {
|
||||
__u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
|
||||
__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
|
||||
__u32 compat_syscall_map[0]; /* No compat syscalls on PPC32 */
|
||||
struct vdso_data data[CS_BASES];
|
||||
struct vdso_rng_data rng_data;
|
||||
|
||||
struct vdso_data data[CS_BASES] __aligned(1 << CONFIG_PAGE_SHIFT);
|
||||
};
|
||||
|
||||
#endif /* CONFIG_PPC64 */
|
||||
@ -105,29 +107,17 @@ extern struct vdso_arch_data *vdso_data;
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
.macro get_datapage ptr
|
||||
.macro get_datapage ptr offset=0
|
||||
bcl 20, 31, .+4
|
||||
999:
|
||||
mflr \ptr
|
||||
addis \ptr, \ptr, (_vdso_datapage - 999b)@ha
|
||||
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
|
||||
addis \ptr, \ptr, (_vdso_datapage - 999b + \offset)@ha
|
||||
addi \ptr, \ptr, (_vdso_datapage - 999b + \offset)@l
|
||||
.endm
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
.macro get_realdatapage ptr scratch
|
||||
get_datapage \ptr
|
||||
#ifdef CONFIG_TIME_NS
|
||||
lwz \scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
|
||||
xoris \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
|
||||
xori \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
|
||||
cntlzw \scratch, \scratch
|
||||
rlwinm \scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
|
||||
add \ptr, \ptr, \scratch
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -335,7 +335,6 @@ int main(void)
|
||||
|
||||
/* datapage offsets for use by vdso */
|
||||
OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data);
|
||||
OFFSET(VDSO_RNG_DATA_OFFSET, vdso_arch_data, rng_data);
|
||||
OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec);
|
||||
#ifdef CONFIG_PPC64
|
||||
OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size);
|
||||
|
@ -48,12 +48,13 @@ long sys_ni_syscall(void);
|
||||
*/
|
||||
static union {
|
||||
struct vdso_arch_data data;
|
||||
u8 page[PAGE_SIZE];
|
||||
u8 page[2 * PAGE_SIZE];
|
||||
} vdso_data_store __page_aligned_data;
|
||||
struct vdso_arch_data *vdso_data = &vdso_data_store.data;
|
||||
|
||||
enum vvar_pages {
|
||||
VVAR_DATA_PAGE_OFFSET,
|
||||
VVAR_BASE_PAGE_OFFSET,
|
||||
VVAR_TIME_PAGE_OFFSET,
|
||||
VVAR_TIMENS_PAGE_OFFSET,
|
||||
VVAR_NR_PAGES,
|
||||
};
|
||||
@ -119,7 +120,7 @@ static struct vm_special_mapping vdso64_spec __ro_after_init = {
|
||||
#ifdef CONFIG_TIME_NS
|
||||
struct vdso_data *arch_get_vdso_data(void *vvar_page)
|
||||
{
|
||||
return ((struct vdso_arch_data *)vvar_page)->data;
|
||||
return vvar_page;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -153,11 +154,14 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
|
||||
unsigned long pfn;
|
||||
|
||||
switch (vmf->pgoff) {
|
||||
case VVAR_DATA_PAGE_OFFSET:
|
||||
case VVAR_BASE_PAGE_OFFSET:
|
||||
pfn = virt_to_pfn(vdso_data);
|
||||
break;
|
||||
case VVAR_TIME_PAGE_OFFSET:
|
||||
if (timens_page)
|
||||
pfn = page_to_pfn(timens_page);
|
||||
else
|
||||
pfn = virt_to_pfn(vdso_data);
|
||||
pfn = virt_to_pfn(vdso_data->data);
|
||||
break;
|
||||
#ifdef CONFIG_TIME_NS
|
||||
case VVAR_TIMENS_PAGE_OFFSET:
|
||||
@ -170,7 +174,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
|
||||
*/
|
||||
if (!timens_page)
|
||||
return VM_FAULT_SIGBUS;
|
||||
pfn = virt_to_pfn(vdso_data);
|
||||
pfn = virt_to_pfn(vdso_data->data);
|
||||
break;
|
||||
#endif /* CONFIG_TIME_NS */
|
||||
default:
|
||||
|
@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
|
||||
#ifdef CONFIG_PPC64
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_realdatapage r10, r11
|
||||
get_datapage r10
|
||||
mtlr r12
|
||||
.cfi_restore lr
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
mr. r4,r3
|
||||
get_realdatapage r3, r11
|
||||
get_datapage r3
|
||||
mtlr r12
|
||||
#ifdef __powerpc64__
|
||||
addi r3,r3,CFG_SYSCALL_MAP64
|
||||
@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
|
||||
.cfi_startproc
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_realdatapage r3, r11
|
||||
get_datapage r3
|
||||
#ifndef __powerpc64__
|
||||
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
|
||||
#endif
|
||||
|
@ -31,8 +31,6 @@
|
||||
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
||||
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
|
||||
#endif
|
||||
get_realdatapage r8, r11
|
||||
addi r8, r8, VDSO_RNG_DATA_OFFSET
|
||||
bl CFUNC(DOTSYM(\funct))
|
||||
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
||||
#ifdef __powerpc64__
|
||||
|
@ -32,11 +32,10 @@
|
||||
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
||||
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
|
||||
#endif
|
||||
get_datapage r5
|
||||
.ifeq \call_time
|
||||
addi r5, r5, VDSO_DATA_OFFSET
|
||||
get_datapage r5 VDSO_DATA_OFFSET
|
||||
.else
|
||||
addi r4, r5, VDSO_DATA_OFFSET
|
||||
get_datapage r4 VDSO_DATA_OFFSET
|
||||
.endif
|
||||
bl CFUNC(DOTSYM(\funct))
|
||||
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
||||
|
@ -16,7 +16,7 @@ OUTPUT_ARCH(powerpc:common)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
PROVIDE(_vdso_datapage = . - 2 * PAGE_SIZE);
|
||||
PROVIDE(_vdso_datapage = . - 3 * PAGE_SIZE);
|
||||
. = SIZEOF_HEADERS;
|
||||
|
||||
.hash : { *(.hash) } :text
|
||||
|
@ -16,7 +16,7 @@ OUTPUT_ARCH(powerpc:common64)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
PROVIDE(_vdso_datapage = . - 2 * PAGE_SIZE);
|
||||
PROVIDE(_vdso_datapage = . - 3 * PAGE_SIZE);
|
||||
. = SIZEOF_HEADERS;
|
||||
|
||||
.hash : { *(.hash) } :text
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
|
||||
size_t opaque_len, const struct vdso_rng_data *vd)
|
||||
size_t opaque_len)
|
||||
{
|
||||
return __cvdso_getrandom_data(vd, buffer, len, flags, opaque_state, opaque_len);
|
||||
return __cvdso_getrandom(buffer, len, flags, opaque_state, opaque_len);
|
||||
}
|
||||
|
@ -222,8 +222,7 @@ void *vdso_sym(const char *version, const char *name)
|
||||
ELF(Sym) *sym = &vdso_info.symtab[chain];
|
||||
|
||||
/* Check for a defined global or weak function w/ right name. */
|
||||
if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC &&
|
||||
ELF64_ST_TYPE(sym->st_info) != STT_NOTYPE)
|
||||
if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
|
||||
continue;
|
||||
if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
|
||||
ELF64_ST_BIND(sym->st_info) != STB_WEAK)
|
||||
|
Loading…
Reference in New Issue
Block a user