mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 09:13:20 -05:00
This pull request contains the following changes for UML:
- Make stub data pages configurable - Make it harder to mix user and kernel code by accident -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAmRSslcWHHJpY2hhcmRA c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wVbGEADWL/4rcVNqaD/b9V3bUXDkNhpG 81Jc9fXcx3OXV87GsxfadiQI05UaOhTAMWJlsdKUF0/IW5tSQSZc0QcDNxTs6aS1 NDkWvjk8s8OpbqdmV0cNKFmaeginrH4AuASajvNleU0BxX4ziqw6BPadih+wGVGz iVEd/M5YH2yet33pvD7Wzh3KZOPlo2OOKBqXzE6Snc3yoOiIfN95U8Cl23nxzMI4 F235LS5m+4+GWIMkYs6+hlWEa8SxSnsH/beQJxAybtetSHRxsDXOHlEpDI9olxYI +OFNqsFLDyhyjib2Snwt8HMES9VmMfUUwT7ZK1cChXN8Quix3lXAyz6rpocmdnL/ X1tzqWb1bz+yqrVRjtN3AGbcav+sQp4UWXsoExVsiz3lzaXfrbPvRZFucH2+SStK Wadyy2v2rHZKNq9sDLUBf5GJ0C4LrBAyT15ADim2L5/K7pZyI7AKSPcdU0Xc8m5y kMswml7FLaI+gsuKOBl7jySaoNDiVZFvQjsxd1+hn5cBNOcyBSt2rSErDw3geJgn pFzVkLtklfxMpHMm+bwXONBZMrXOBPNgo0gSkVrCVzO68x6j/MaBGLFazSqOKxbc UcVULhiomjIae4AcTomzOQx7oM1Xs3XuPo0x2RgJ3gMlCCZKoDNuqDgB3ZmPP/gq cbbHHveXEx7aMOPz0A== =Qb+I -----END PGP SIGNATURE----- Merge tag 'uml-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux Pull uml updates from Richard Weinberger: - Make stub data pages configurable - Make it harder to mix user and kernel code by accident * tag 'uml-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux: um: make stub data pages size tweakable um: prevent user code in modules um: further clean up user_syms um: don't export printf() um: hostfs: define our own API boundary um: add __weak for exported functions
This commit is contained in:
commit
342528ff00
13 changed files with 78 additions and 114 deletions
|
@ -23,7 +23,8 @@
|
||||||
#define STUB_START stub_start
|
#define STUB_START stub_start
|
||||||
#define STUB_CODE STUB_START
|
#define STUB_CODE STUB_START
|
||||||
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
|
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
|
||||||
#define STUB_END (STUB_DATA + UM_KERN_PAGE_SIZE)
|
#define STUB_DATA_PAGES 1 /* must be a power of two */
|
||||||
|
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,12 @@
|
||||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
stub_clone_handler(void)
|
stub_clone_handler(void)
|
||||||
{
|
{
|
||||||
struct stub_data *data = get_stub_page();
|
struct stub_data *data = get_stub_data();
|
||||||
long err;
|
long err;
|
||||||
|
|
||||||
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
||||||
(unsigned long)data + UM_KERN_PAGE_SIZE / 2);
|
(unsigned long)data +
|
||||||
|
STUB_DATA_PAGES * UM_KERN_PAGE_SIZE / 2);
|
||||||
if (err) {
|
if (err) {
|
||||||
data->parent_err = err;
|
data->parent_err = err;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
@ -21,7 +21,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||||
unsigned long stack = 0;
|
unsigned long stack = 0;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
stack = get_zeroed_page(GFP_KERNEL);
|
stack = __get_free_pages(GFP_KERNEL | __GFP_ZERO, ilog2(STUB_DATA_PAGES));
|
||||||
if (stack == 0)
|
if (stack == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
if (to_mm->id.stack != 0)
|
if (to_mm->id.stack != 0)
|
||||||
free_page(to_mm->id.stack);
|
free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,6 @@ void destroy_context(struct mm_struct *mm)
|
||||||
}
|
}
|
||||||
os_kill_ptraced_process(mmu->id.u.pid, 1);
|
os_kill_ptraced_process(mmu->id.u.pid, 1);
|
||||||
|
|
||||||
free_page(mmu->id.stack);
|
free_pages(mmu->id.stack, ilog2(STUB_DATA_PAGES));
|
||||||
free_ldt(mmu);
|
free_ldt(mmu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,9 +326,13 @@ int __init linux_main(int argc, char **argv)
|
||||||
add_arg(DEFAULT_COMMAND_LINE_CONSOLE);
|
add_arg(DEFAULT_COMMAND_LINE_CONSOLE);
|
||||||
|
|
||||||
host_task_size = os_get_top_address();
|
host_task_size = os_get_top_address();
|
||||||
/* reserve two pages for the stubs */
|
/* reserve a few pages for the stubs (taking care of data alignment) */
|
||||||
host_task_size -= 2 * PAGE_SIZE;
|
/* align the data portion */
|
||||||
stub_start = host_task_size;
|
BUILD_BUG_ON(!is_power_of_2(STUB_DATA_PAGES));
|
||||||
|
stub_start = (host_task_size - 1) & ~(STUB_DATA_PAGES * PAGE_SIZE - 1);
|
||||||
|
/* another page for the code portion */
|
||||||
|
stub_start -= PAGE_SIZE;
|
||||||
|
host_task_size = stub_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
|
* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
|
||||||
|
|
|
@ -262,7 +262,7 @@ static int userspace_tramp(void *stack)
|
||||||
if (stack != NULL) {
|
if (stack != NULL) {
|
||||||
fd = phys_mapping(uml_to_phys(stack), &offset);
|
fd = phys_mapping(uml_to_phys(stack), &offset);
|
||||||
addr = mmap((void *) STUB_DATA,
|
addr = mmap((void *) STUB_DATA,
|
||||||
UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||||
MAP_FIXED | MAP_SHARED, fd, offset);
|
MAP_FIXED | MAP_SHARED, fd, offset);
|
||||||
if (addr == MAP_FAILED) {
|
if (addr == MAP_FAILED) {
|
||||||
printk(UM_KERN_ERR "mapping segfault stack at 0x%lx failed, errno = %d\n",
|
printk(UM_KERN_ERR "mapping segfault stack at 0x%lx failed, errno = %d\n",
|
||||||
|
@ -277,7 +277,7 @@ static int userspace_tramp(void *stack)
|
||||||
(unsigned long) stub_segv_handler -
|
(unsigned long) stub_segv_handler -
|
||||||
(unsigned long) __syscall_stub_start;
|
(unsigned long) __syscall_stub_start;
|
||||||
|
|
||||||
set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
|
set_sigstack((void *) STUB_DATA, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
|
sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
|
||||||
sa.sa_sigaction = (void *) v;
|
sa.sa_sigaction = (void *) v;
|
||||||
|
@ -515,7 +515,7 @@ static int __init init_thread_regs(void)
|
||||||
thread_regs[REGS_IP_INDEX] = STUB_CODE +
|
thread_regs[REGS_IP_INDEX] = STUB_CODE +
|
||||||
(unsigned long) stub_clone_handler -
|
(unsigned long) stub_clone_handler -
|
||||||
(unsigned long) __syscall_stub_start;
|
(unsigned long) __syscall_stub_start;
|
||||||
thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
|
thread_regs[REGS_SP_INDEX] = STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE -
|
||||||
sizeof(void *);
|
sizeof(void *);
|
||||||
#ifdef __SIGNAL_FRAMESIZE
|
#ifdef __SIGNAL_FRAMESIZE
|
||||||
thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
|
thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
|
||||||
|
|
|
@ -3,112 +3,40 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
/* Some of this are builtin function (some are not but could in the future),
|
/*
|
||||||
* so I *must* declare good prototypes for them and then EXPORT them.
|
* This file exports some critical string functions and compiler
|
||||||
* The kernel code uses the macro defined by include/linux/string.h,
|
* built-in functions (where calls are emitted by the compiler
|
||||||
* so I undef macros; the userspace code does not include that and I
|
* itself that we cannot avoid even in kernel code) to modules.
|
||||||
* add an EXPORT for the glibc one.
|
*
|
||||||
|
* "_user.c" code that previously used exports here such as hostfs
|
||||||
|
* really should be considered part of the 'hypervisor' and define
|
||||||
|
* its own API boundary like hostfs does now; don't add exports to
|
||||||
|
* this file for such cases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef strlen
|
|
||||||
#undef strstr
|
|
||||||
#undef memcpy
|
|
||||||
#undef memset
|
|
||||||
|
|
||||||
extern size_t strlen(const char *);
|
|
||||||
extern void *memmove(void *, const void *, size_t);
|
|
||||||
extern void *memset(void *, int, size_t);
|
|
||||||
extern int printf(const char *, ...);
|
|
||||||
|
|
||||||
/* If it's not defined, the export is included in lib/string.c.*/
|
/* If it's not defined, the export is included in lib/string.c.*/
|
||||||
#ifdef __HAVE_ARCH_STRSTR
|
#ifdef __HAVE_ARCH_STRSTR
|
||||||
|
#undef strstr
|
||||||
EXPORT_SYMBOL(strstr);
|
EXPORT_SYMBOL(strstr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __x86_64__
|
#ifndef __x86_64__
|
||||||
|
#undef memcpy
|
||||||
extern void *memcpy(void *, const void *, size_t);
|
extern void *memcpy(void *, const void *, size_t);
|
||||||
EXPORT_SYMBOL(memcpy);
|
EXPORT_SYMBOL(memcpy);
|
||||||
|
extern void *memmove(void *, const void *, size_t);
|
||||||
EXPORT_SYMBOL(memmove);
|
EXPORT_SYMBOL(memmove);
|
||||||
|
#undef memset
|
||||||
|
extern void *memset(void *, int, size_t);
|
||||||
EXPORT_SYMBOL(memset);
|
EXPORT_SYMBOL(memset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPORT_SYMBOL(printf);
|
|
||||||
|
|
||||||
/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
|
|
||||||
* However, the modules will use the CRC defined *here*, no matter if it is
|
|
||||||
* good; so the versions of these symbols will always match
|
|
||||||
*/
|
|
||||||
#define EXPORT_SYMBOL_PROTO(sym) \
|
|
||||||
int sym(void); \
|
|
||||||
EXPORT_SYMBOL(sym);
|
|
||||||
|
|
||||||
extern void readdir64(void) __attribute__((weak));
|
|
||||||
EXPORT_SYMBOL(readdir64);
|
|
||||||
extern void truncate64(void) __attribute__((weak));
|
|
||||||
EXPORT_SYMBOL(truncate64);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
|
#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
|
||||||
|
/* needed for __access_ok() */
|
||||||
EXPORT_SYMBOL(vsyscall_ehdr);
|
EXPORT_SYMBOL(vsyscall_ehdr);
|
||||||
EXPORT_SYMBOL(vsyscall_end);
|
EXPORT_SYMBOL(vsyscall_end);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(__errno_location);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(access);
|
|
||||||
EXPORT_SYMBOL_PROTO(open);
|
|
||||||
EXPORT_SYMBOL_PROTO(open64);
|
|
||||||
EXPORT_SYMBOL_PROTO(close);
|
|
||||||
EXPORT_SYMBOL_PROTO(read);
|
|
||||||
EXPORT_SYMBOL_PROTO(write);
|
|
||||||
EXPORT_SYMBOL_PROTO(dup2);
|
|
||||||
EXPORT_SYMBOL_PROTO(__xstat);
|
|
||||||
EXPORT_SYMBOL_PROTO(__lxstat);
|
|
||||||
EXPORT_SYMBOL_PROTO(__lxstat64);
|
|
||||||
EXPORT_SYMBOL_PROTO(__fxstat64);
|
|
||||||
EXPORT_SYMBOL_PROTO(lseek);
|
|
||||||
EXPORT_SYMBOL_PROTO(lseek64);
|
|
||||||
EXPORT_SYMBOL_PROTO(chown);
|
|
||||||
EXPORT_SYMBOL_PROTO(fchown);
|
|
||||||
EXPORT_SYMBOL_PROTO(truncate);
|
|
||||||
EXPORT_SYMBOL_PROTO(ftruncate64);
|
|
||||||
EXPORT_SYMBOL_PROTO(utime);
|
|
||||||
EXPORT_SYMBOL_PROTO(utimes);
|
|
||||||
EXPORT_SYMBOL_PROTO(futimes);
|
|
||||||
EXPORT_SYMBOL_PROTO(chmod);
|
|
||||||
EXPORT_SYMBOL_PROTO(fchmod);
|
|
||||||
EXPORT_SYMBOL_PROTO(rename);
|
|
||||||
EXPORT_SYMBOL_PROTO(__xmknod);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(symlink);
|
|
||||||
EXPORT_SYMBOL_PROTO(link);
|
|
||||||
EXPORT_SYMBOL_PROTO(unlink);
|
|
||||||
EXPORT_SYMBOL_PROTO(readlink);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(mkdir);
|
|
||||||
EXPORT_SYMBOL_PROTO(rmdir);
|
|
||||||
EXPORT_SYMBOL_PROTO(opendir);
|
|
||||||
EXPORT_SYMBOL_PROTO(readdir);
|
|
||||||
EXPORT_SYMBOL_PROTO(closedir);
|
|
||||||
EXPORT_SYMBOL_PROTO(seekdir);
|
|
||||||
EXPORT_SYMBOL_PROTO(telldir);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(ioctl);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(pread64);
|
|
||||||
EXPORT_SYMBOL_PROTO(pwrite64);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(statfs);
|
|
||||||
EXPORT_SYMBOL_PROTO(statfs64);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(getuid);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(fsync);
|
|
||||||
EXPORT_SYMBOL_PROTO(fdatasync);
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_PROTO(lstat64);
|
|
||||||
EXPORT_SYMBOL_PROTO(fstat64);
|
|
||||||
EXPORT_SYMBOL_PROTO(mknod);
|
|
||||||
|
|
||||||
/* Export symbols used by GCC for the stack protector. */
|
/* Export symbols used by GCC for the stack protector. */
|
||||||
extern void __stack_smash_handler(void *) __attribute__((weak));
|
extern void __stack_smash_handler(void *) __attribute__((weak));
|
||||||
EXPORT_SYMBOL(__stack_smash_handler);
|
EXPORT_SYMBOL(__stack_smash_handler);
|
||||||
|
@ -117,6 +45,6 @@ extern long __guard __attribute__((weak));
|
||||||
EXPORT_SYMBOL(__guard);
|
EXPORT_SYMBOL(__guard);
|
||||||
|
|
||||||
#ifdef _FORTIFY_SOURCE
|
#ifdef _FORTIFY_SOURCE
|
||||||
extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format);
|
extern int __sprintf_chk(char *str, int flag, size_t len, const char *format);
|
||||||
EXPORT_SYMBOL(__sprintf_chk);
|
EXPORT_SYMBOL(__sprintf_chk);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
||||||
USER_SINGLE_OBJS := \
|
USER_SINGLE_OBJS := \
|
||||||
$(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
|
$(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
|
||||||
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
|
USER_OBJS += $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
|
||||||
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
|
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
|
||||||
|
|
||||||
$(USER_OBJS:.o=.%): \
|
$(USER_OBJS:.o=.%): \
|
||||||
|
|
|
@ -89,19 +89,19 @@ static inline void remap_stack_and_trap(void)
|
||||||
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
|
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
|
||||||
"int $3"
|
"int $3"
|
||||||
: :
|
: :
|
||||||
"g" (~(UM_KERN_PAGE_SIZE - 1)),
|
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
|
||||||
"g" (STUB_MMAP_NR),
|
"g" (STUB_MMAP_NR),
|
||||||
"g" (UML_STUB_FIELD_FD),
|
"g" (UML_STUB_FIELD_FD),
|
||||||
"g" (UML_STUB_FIELD_OFFSET),
|
"g" (UML_STUB_FIELD_OFFSET),
|
||||||
"g" (UML_STUB_FIELD_CHILD_ERR),
|
"g" (UML_STUB_FIELD_CHILD_ERR),
|
||||||
"c" (UM_KERN_PAGE_SIZE),
|
"c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
|
||||||
"d" (PROT_READ | PROT_WRITE),
|
"d" (PROT_READ | PROT_WRITE),
|
||||||
"S" (MAP_FIXED | MAP_SHARED)
|
"S" (MAP_FIXED | MAP_SHARED)
|
||||||
:
|
:
|
||||||
"memory");
|
"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void *get_stub_page(void)
|
static __always_inline void *get_stub_data(void)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ static __always_inline void *get_stub_page(void)
|
||||||
"movl %%esp,%0 ;"
|
"movl %%esp,%0 ;"
|
||||||
"andl %1,%0"
|
"andl %1,%0"
|
||||||
: "=a" (ret)
|
: "=a" (ret)
|
||||||
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
|
: "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
|
||||||
|
|
||||||
return (void *)ret;
|
return (void *)ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,18 +98,18 @@ static inline void remap_stack_and_trap(void)
|
||||||
"int3"
|
"int3"
|
||||||
: :
|
: :
|
||||||
"g" (STUB_MMAP_NR),
|
"g" (STUB_MMAP_NR),
|
||||||
"g" (~(UM_KERN_PAGE_SIZE - 1)),
|
"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
|
||||||
"g" (MAP_FIXED | MAP_SHARED),
|
"g" (MAP_FIXED | MAP_SHARED),
|
||||||
"g" (UML_STUB_FIELD_FD),
|
"g" (UML_STUB_FIELD_FD),
|
||||||
"g" (UML_STUB_FIELD_OFFSET),
|
"g" (UML_STUB_FIELD_OFFSET),
|
||||||
"g" (UML_STUB_FIELD_CHILD_ERR),
|
"g" (UML_STUB_FIELD_CHILD_ERR),
|
||||||
"S" (UM_KERN_PAGE_SIZE),
|
"S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
|
||||||
"d" (PROT_READ | PROT_WRITE)
|
"d" (PROT_READ | PROT_WRITE)
|
||||||
:
|
:
|
||||||
__syscall_clobber, "r10", "r8", "r9");
|
__syscall_clobber, "r10", "r8", "r9");
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void *get_stub_page(void)
|
static __always_inline void *get_stub_data(void)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ static __always_inline void *get_stub_page(void)
|
||||||
"movq %%rsp,%0 ;"
|
"movq %%rsp,%0 ;"
|
||||||
"andq %1,%0"
|
"andq %1,%0"
|
||||||
: "=a" (ret)
|
: "=a" (ret)
|
||||||
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
|
: "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
|
||||||
|
|
||||||
return (void *)ret;
|
return (void *)ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
stub_segv_handler(int sig, siginfo_t *info, void *p)
|
stub_segv_handler(int sig, siginfo_t *info, void *p)
|
||||||
{
|
{
|
||||||
struct faultinfo *f = get_stub_page();
|
struct faultinfo *f = get_stub_data();
|
||||||
ucontext_t *uc = p;
|
ucontext_t *uc = p;
|
||||||
|
|
||||||
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
|
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
|
||||||
|
|
|
@ -123,7 +123,7 @@ obj-$(CONFIG_9P_FS) += 9p/
|
||||||
obj-$(CONFIG_AFS_FS) += afs/
|
obj-$(CONFIG_AFS_FS) += afs/
|
||||||
obj-$(CONFIG_NILFS2_FS) += nilfs2/
|
obj-$(CONFIG_NILFS2_FS) += nilfs2/
|
||||||
obj-$(CONFIG_BEFS_FS) += befs/
|
obj-$(CONFIG_BEFS_FS) += befs/
|
||||||
obj-$(CONFIG_HOSTFS) += hostfs/
|
obj-y += hostfs/
|
||||||
obj-$(CONFIG_CACHEFILES) += cachefiles/
|
obj-$(CONFIG_CACHEFILES) += cachefiles/
|
||||||
obj-$(CONFIG_DEBUG_FS) += debugfs/
|
obj-$(CONFIG_DEBUG_FS) += debugfs/
|
||||||
obj-$(CONFIG_TRACING) += tracefs/
|
obj-$(CONFIG_TRACING) += tracefs/
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
# Licensed under the GPL
|
# Licensed under the GPL
|
||||||
#
|
#
|
||||||
|
|
||||||
hostfs-objs := hostfs_kern.o hostfs_user.o
|
hostfs-objs := hostfs_kern.o
|
||||||
|
|
||||||
obj-y :=
|
hostfs-builtin-$(CONFIG_HOSTFS) += hostfs_user.o hostfs_user_exp.o
|
||||||
|
|
||||||
|
obj-y := $(hostfs-builtin-y) $(hostfs-builtin-m)
|
||||||
obj-$(CONFIG_HOSTFS) += hostfs.o
|
obj-$(CONFIG_HOSTFS) += hostfs.o
|
||||||
|
|
||||||
include $(srctree)/arch/um/scripts/Makefile.rules
|
include $(srctree)/arch/um/scripts/Makefile.rules
|
||||||
|
|
28
fs/hostfs/hostfs_user_exp.c
Normal file
28
fs/hostfs/hostfs_user_exp.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include "hostfs.h"
|
||||||
|
|
||||||
|
EXPORT_SYMBOL_GPL(stat_file);
|
||||||
|
EXPORT_SYMBOL_GPL(access_file);
|
||||||
|
EXPORT_SYMBOL_GPL(open_file);
|
||||||
|
EXPORT_SYMBOL_GPL(open_dir);
|
||||||
|
EXPORT_SYMBOL_GPL(seek_dir);
|
||||||
|
EXPORT_SYMBOL_GPL(read_dir);
|
||||||
|
EXPORT_SYMBOL_GPL(read_file);
|
||||||
|
EXPORT_SYMBOL_GPL(write_file);
|
||||||
|
EXPORT_SYMBOL_GPL(lseek_file);
|
||||||
|
EXPORT_SYMBOL_GPL(fsync_file);
|
||||||
|
EXPORT_SYMBOL_GPL(replace_file);
|
||||||
|
EXPORT_SYMBOL_GPL(close_file);
|
||||||
|
EXPORT_SYMBOL_GPL(close_dir);
|
||||||
|
EXPORT_SYMBOL_GPL(file_create);
|
||||||
|
EXPORT_SYMBOL_GPL(set_attr);
|
||||||
|
EXPORT_SYMBOL_GPL(make_symlink);
|
||||||
|
EXPORT_SYMBOL_GPL(unlink_file);
|
||||||
|
EXPORT_SYMBOL_GPL(do_mkdir);
|
||||||
|
EXPORT_SYMBOL_GPL(hostfs_do_rmdir);
|
||||||
|
EXPORT_SYMBOL_GPL(do_mknod);
|
||||||
|
EXPORT_SYMBOL_GPL(link_file);
|
||||||
|
EXPORT_SYMBOL_GPL(hostfs_do_readlink);
|
||||||
|
EXPORT_SYMBOL_GPL(rename_file);
|
||||||
|
EXPORT_SYMBOL_GPL(rename2_file);
|
||||||
|
EXPORT_SYMBOL_GPL(do_statfs);
|
Loading…
Add table
Reference in a new issue