mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Merge branch 'akpm' (patches from Andrew)
Merge third set of updates from Andrew Morton: - the rest of MM [ This includes getting rid of the numa hinting bits, in favor of just generic protnone logic. Yay. - Linus ] - core kernel - procfs - some of lib/ (lots of lib/ material this time) * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (104 commits) lib/lcm.c: replace include lib/percpu_ida.c: remove redundant includes lib/strncpy_from_user.c: replace module.h include lib/stmp_device.c: replace module.h include lib/sort.c: move include inside #if 0 lib/show_mem.c: remove redundant include lib/radix-tree.c: change to simpler include lib/plist.c: remove redundant include lib/nlattr.c: remove redundant include lib/kobject_uevent.c: remove redundant include lib/llist.c: remove redundant include lib/md5.c: simplify include lib/list_sort.c: rearrange includes lib/genalloc.c: remove redundant include lib/idr.c: remove redundant include lib/halfmd4.c: simplify includes lib/dynamic_queue_limits.c: simplify includes lib/sort.c: use simpler includes lib/interval_tree.c: simplify includes hexdump: make it return number of bytes placed in buffer ...
This commit is contained in:
commit
818099574b
207 changed files with 2216 additions and 1422 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -52,6 +52,11 @@ Module.symvers
|
||||||
#
|
#
|
||||||
/debian/
|
/debian/
|
||||||
|
|
||||||
|
#
|
||||||
|
# tar directory (make tar*-pkg)
|
||||||
|
#
|
||||||
|
/tar-install/
|
||||||
|
|
||||||
#
|
#
|
||||||
# git files that we don't want to ignore even it they are dot-files
|
# git files that we don't want to ignore even it they are dot-files
|
||||||
#
|
#
|
||||||
|
|
|
@ -145,6 +145,8 @@ Table 1-1: Process specific entries in /proc
|
||||||
stack Report full stack trace, enable via CONFIG_STACKTRACE
|
stack Report full stack trace, enable via CONFIG_STACKTRACE
|
||||||
smaps a extension based on maps, showing the memory consumption of
|
smaps a extension based on maps, showing the memory consumption of
|
||||||
each mapping and flags associated with it
|
each mapping and flags associated with it
|
||||||
|
numa_maps an extension based on maps, showing the memory locality and
|
||||||
|
binding policy as well as mem usage (in pages) of each mapping.
|
||||||
..............................................................................
|
..............................................................................
|
||||||
|
|
||||||
For example, to get the status information of a process, all you have to do is
|
For example, to get the status information of a process, all you have to do is
|
||||||
|
@ -489,12 +491,47 @@ To clear the bits for the file mapped pages associated with the process
|
||||||
To clear the soft-dirty bit
|
To clear the soft-dirty bit
|
||||||
> echo 4 > /proc/PID/clear_refs
|
> echo 4 > /proc/PID/clear_refs
|
||||||
|
|
||||||
|
To reset the peak resident set size ("high water mark") to the process's
|
||||||
|
current value:
|
||||||
|
> echo 5 > /proc/PID/clear_refs
|
||||||
|
|
||||||
Any other value written to /proc/PID/clear_refs will have no effect.
|
Any other value written to /proc/PID/clear_refs will have no effect.
|
||||||
|
|
||||||
The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags
|
The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags
|
||||||
using /proc/kpageflags and number of times a page is mapped using
|
using /proc/kpageflags and number of times a page is mapped using
|
||||||
/proc/kpagecount. For detailed explanation, see Documentation/vm/pagemap.txt.
|
/proc/kpagecount. For detailed explanation, see Documentation/vm/pagemap.txt.
|
||||||
|
|
||||||
|
The /proc/pid/numa_maps is an extension based on maps, showing the memory
|
||||||
|
locality and binding policy, as well as the memory usage (in pages) of
|
||||||
|
each mapping. The output follows a general format where mapping details get
|
||||||
|
summarized separated by blank spaces, one mapping per each file line:
|
||||||
|
|
||||||
|
address policy mapping details
|
||||||
|
|
||||||
|
00400000 default file=/usr/local/bin/app mapped=1 active=0 N3=1 kernelpagesize_kB=4
|
||||||
|
00600000 default file=/usr/local/bin/app anon=1 dirty=1 N3=1 kernelpagesize_kB=4
|
||||||
|
3206000000 default file=/lib64/ld-2.12.so mapped=26 mapmax=6 N0=24 N3=2 kernelpagesize_kB=4
|
||||||
|
320621f000 default file=/lib64/ld-2.12.so anon=1 dirty=1 N3=1 kernelpagesize_kB=4
|
||||||
|
3206220000 default file=/lib64/ld-2.12.so anon=1 dirty=1 N3=1 kernelpagesize_kB=4
|
||||||
|
3206221000 default anon=1 dirty=1 N3=1 kernelpagesize_kB=4
|
||||||
|
3206800000 default file=/lib64/libc-2.12.so mapped=59 mapmax=21 active=55 N0=41 N3=18 kernelpagesize_kB=4
|
||||||
|
320698b000 default file=/lib64/libc-2.12.so
|
||||||
|
3206b8a000 default file=/lib64/libc-2.12.so anon=2 dirty=2 N3=2 kernelpagesize_kB=4
|
||||||
|
3206b8e000 default file=/lib64/libc-2.12.so anon=1 dirty=1 N3=1 kernelpagesize_kB=4
|
||||||
|
3206b8f000 default anon=3 dirty=3 active=1 N3=3 kernelpagesize_kB=4
|
||||||
|
7f4dc10a2000 default anon=3 dirty=3 N3=3 kernelpagesize_kB=4
|
||||||
|
7f4dc10b4000 default anon=2 dirty=2 active=1 N3=2 kernelpagesize_kB=4
|
||||||
|
7f4dc1200000 default file=/anon_hugepage\040(deleted) huge anon=1 dirty=1 N3=1 kernelpagesize_kB=2048
|
||||||
|
7fff335f0000 default stack anon=3 dirty=3 N3=3 kernelpagesize_kB=4
|
||||||
|
7fff3369d000 default mapped=1 mapmax=35 active=0 N3=1 kernelpagesize_kB=4
|
||||||
|
|
||||||
|
Where:
|
||||||
|
"address" is the starting address for the mapping;
|
||||||
|
"policy" reports the NUMA memory policy set for the mapping (see vm/numa_memory_policy.txt);
|
||||||
|
"mapping details" summarizes mapping data such as mapping type, page usage counters,
|
||||||
|
node locality page counters (N0 == node0, N1 == node1, ...) and the kernel page
|
||||||
|
size, in KB, that is backing the mapping up.
|
||||||
|
|
||||||
1.2 Kernel data
|
1.2 Kernel data
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,6 @@ struct thread_info {
|
||||||
int bpt_nsaved;
|
int bpt_nsaved;
|
||||||
unsigned long bpt_addr[2]; /* breakpoint handling */
|
unsigned long bpt_addr[2]; /* breakpoint handling */
|
||||||
unsigned int bpt_insn[2];
|
unsigned int bpt_insn[2];
|
||||||
|
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,9 +38,6 @@ struct thread_info {
|
||||||
.exec_domain = &default_exec_domain, \
|
.exec_domain = &default_exec_domain, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -150,7 +150,7 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
|
||||||
struct switch_stack *sw = (struct switch_stack *)regs - 1;
|
struct switch_stack *sw = (struct switch_stack *)regs - 1;
|
||||||
long i, err = __get_user(regs->pc, &sc->sc_pc);
|
long i, err = __get_user(regs->pc, &sc->sc_pc);
|
||||||
|
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
sw->r26 = (unsigned long) ret_from_sys_call;
|
sw->r26 = (unsigned long) ret_from_sys_call;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ struct thread_info {
|
||||||
struct exec_domain *exec_domain;/* execution domain */
|
struct exec_domain *exec_domain;/* execution domain */
|
||||||
__u32 cpu; /* current CPU */
|
__u32 cpu; /* current CPU */
|
||||||
unsigned long thr_ptr; /* TLS ptr */
|
unsigned long thr_ptr; /* TLS ptr */
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -62,9 +61,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -104,7 +104,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
|
||||||
struct pt_regs *regs = current_pt_regs();
|
struct pt_regs *regs = current_pt_regs();
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* Since we stacked the signal on a word boundary,
|
/* Since we stacked the signal on a word boundary,
|
||||||
* then 'sp' should be word aligned here. If it's
|
* then 'sp' should be word aligned here. If it's
|
||||||
|
|
|
@ -257,7 +257,10 @@ PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
|
||||||
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
|
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
|
||||||
|
|
||||||
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
|
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
|
||||||
#define pmd_mknotpresent(pmd) (__pmd(0))
|
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return __pmd(0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,6 @@ struct thread_info {
|
||||||
#ifdef CONFIG_ARM_THUMBEE
|
#ifdef CONFIG_ARM_THUMBEE
|
||||||
unsigned long thumbee_state; /* ThumbEE Handler Base register */
|
unsigned long thumbee_state; /* ThumbEE Handler Base register */
|
||||||
#endif
|
#endif
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_THREAD_INFO(tsk) \
|
#define INIT_THREAD_INFO(tsk) \
|
||||||
|
@ -81,9 +80,6 @@ struct thread_info {
|
||||||
.cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
|
.cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
|
||||||
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
|
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
|
||||||
domain_val(DOMAIN_IO, DOMAIN_CLIENT), \
|
domain_val(DOMAIN_IO, DOMAIN_CLIENT), \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -191,7 +191,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
|
||||||
struct sigframe __user *frame;
|
struct sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 64-bit boundary,
|
* Since we stacked the signal on a 64-bit boundary,
|
||||||
|
@ -221,7 +221,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
struct rt_sigframe __user *frame;
|
struct rt_sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 64-bit boundary,
|
* Since we stacked the signal on a 64-bit boundary,
|
||||||
|
|
|
@ -48,7 +48,6 @@ struct thread_info {
|
||||||
mm_segment_t addr_limit; /* address limit */
|
mm_segment_t addr_limit; /* address limit */
|
||||||
struct task_struct *task; /* main task structure */
|
struct task_struct *task; /* main task structure */
|
||||||
struct exec_domain *exec_domain; /* execution domain */
|
struct exec_domain *exec_domain; /* execution domain */
|
||||||
struct restart_block restart_block;
|
|
||||||
int preempt_count; /* 0 => preemptable, <0 => bug */
|
int preempt_count; /* 0 => preemptable, <0 => bug */
|
||||||
int cpu; /* cpu */
|
int cpu; /* cpu */
|
||||||
};
|
};
|
||||||
|
@ -60,9 +59,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -131,7 +131,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
struct rt_sigframe __user *frame;
|
struct rt_sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 128-bit boundary, then 'sp' should
|
* Since we stacked the signal on a 128-bit boundary, then 'sp' should
|
||||||
|
|
|
@ -347,7 +347,7 @@ asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
|
||||||
struct compat_sigframe __user *frame;
|
struct compat_sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 64-bit boundary,
|
* Since we stacked the signal on a 64-bit boundary,
|
||||||
|
@ -381,7 +381,7 @@ asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
struct compat_rt_sigframe __user *frame;
|
struct compat_rt_sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 64-bit boundary,
|
* Since we stacked the signal on a 64-bit boundary,
|
||||||
|
|
|
@ -30,7 +30,6 @@ struct thread_info {
|
||||||
saved by debug handler
|
saved by debug handler
|
||||||
when setting up
|
when setting up
|
||||||
trampoline */
|
trampoline */
|
||||||
struct restart_block restart_block;
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,9 +40,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -18,7 +18,6 @@ void foo(void)
|
||||||
OFFSET(TI_preempt_count, thread_info, preempt_count);
|
OFFSET(TI_preempt_count, thread_info, preempt_count);
|
||||||
OFFSET(TI_rar_saved, thread_info, rar_saved);
|
OFFSET(TI_rar_saved, thread_info, rar_saved);
|
||||||
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
|
OFFSET(TI_rsr_saved, thread_info, rsr_saved);
|
||||||
OFFSET(TI_restart_block, thread_info, restart_block);
|
|
||||||
BLANK();
|
BLANK();
|
||||||
OFFSET(TSK_active_mm, task_struct, active_mm);
|
OFFSET(TSK_active_mm, task_struct, active_mm);
|
||||||
BLANK();
|
BLANK();
|
||||||
|
|
|
@ -69,7 +69,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
frame = (struct rt_sigframe __user *)regs->sp;
|
frame = (struct rt_sigframe __user *)regs->sp;
|
||||||
pr_debug("SIG return: frame = %p\n", frame);
|
pr_debug("SIG return: frame = %p\n", frame);
|
||||||
|
|
|
@ -42,7 +42,6 @@ struct thread_info {
|
||||||
int cpu; /* cpu we're on */
|
int cpu; /* cpu we're on */
|
||||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||||
mm_segment_t addr_limit; /* address limit */
|
mm_segment_t addr_limit; /* address limit */
|
||||||
struct restart_block restart_block;
|
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
struct l1_scratch_task_info l1_task_info;
|
struct l1_scratch_task_info l1_task_info;
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,9 +57,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
#define init_stack (init_thread_union.stack)
|
#define init_stack (init_thread_union.stack)
|
||||||
|
|
|
@ -44,7 +44,7 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
|
#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ struct thread_info {
|
||||||
int cpu; /* cpu we're on */
|
int cpu; /* cpu we're on */
|
||||||
int preempt_count; /* 0 = preemptable, <0 = BUG */
|
int preempt_count; /* 0 = preemptable, <0 = BUG */
|
||||||
mm_segment_t addr_limit; /* thread address space */
|
mm_segment_t addr_limit; /* thread address space */
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -61,9 +60,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -68,7 +68,7 @@ asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a dword boundary,
|
* Since we stacked the signal on a dword boundary,
|
||||||
|
|
|
@ -67,7 +67,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
unsigned long old_usp;
|
unsigned long old_usp;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* restore the regs from &sc->regs (same as sc, since regs is first)
|
/* restore the regs from &sc->regs (same as sc, since regs is first)
|
||||||
* (sc is already checked for VERIFY_READ since the sigframe was
|
* (sc is already checked for VERIFY_READ since the sigframe was
|
||||||
|
|
|
@ -59,7 +59,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
unsigned long old_usp;
|
unsigned long old_usp;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore the registers from &sc->regs. sc is already checked
|
* Restore the registers from &sc->regs. sc is already checked
|
||||||
|
|
|
@ -38,7 +38,6 @@ struct thread_info {
|
||||||
0-0xBFFFFFFF for user-thead
|
0-0xBFFFFFFF for user-thead
|
||||||
0-0xFFFFFFFF for kernel-thread
|
0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,9 +55,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -33,7 +33,6 @@ extern void *memcpy(void *, const void *, __kernel_size_t);
|
||||||
#define __HAVE_ARCH_STRNCAT 1
|
#define __HAVE_ARCH_STRNCAT 1
|
||||||
#define __HAVE_ARCH_STRCMP 1
|
#define __HAVE_ARCH_STRCMP 1
|
||||||
#define __HAVE_ARCH_STRNCMP 1
|
#define __HAVE_ARCH_STRNCMP 1
|
||||||
#define __HAVE_ARCH_STRNICMP 1
|
|
||||||
#define __HAVE_ARCH_STRCHR 1
|
#define __HAVE_ARCH_STRCHR 1
|
||||||
#define __HAVE_ARCH_STRRCHR 1
|
#define __HAVE_ARCH_STRRCHR 1
|
||||||
#define __HAVE_ARCH_STRSTR 1
|
#define __HAVE_ARCH_STRSTR 1
|
||||||
|
|
|
@ -41,7 +41,6 @@ struct thread_info {
|
||||||
* 0-0xBFFFFFFF for user-thead
|
* 0-0xBFFFFFFF for user-thead
|
||||||
* 0-0xFFFFFFFF for kernel-thread
|
* 0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
};
|
};
|
||||||
|
@ -65,9 +64,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -40,7 +40,6 @@ void foo(void)
|
||||||
OFFSET(TI_CPU, thread_info, cpu);
|
OFFSET(TI_CPU, thread_info, cpu);
|
||||||
OFFSET(TI_PREEMPT_COUNT, thread_info, preempt_count);
|
OFFSET(TI_PREEMPT_COUNT, thread_info, preempt_count);
|
||||||
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
||||||
OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
|
|
||||||
BLANK();
|
BLANK();
|
||||||
|
|
||||||
/* offsets into register file storage */
|
/* offsets into register file storage */
|
||||||
|
|
|
@ -62,7 +62,7 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
|
||||||
unsigned long tbr, psr;
|
unsigned long tbr, psr;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
tbr = user->i.tbr;
|
tbr = user->i.tbr;
|
||||||
psr = user->i.psr;
|
psr = user->i.psr;
|
||||||
|
|
|
@ -10,29 +10,6 @@ extern const void __memset_end, __memset_user_error_lr, __memset_user_error_hand
|
||||||
extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler;
|
extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler;
|
||||||
extern spinlock_t modlist_lock;
|
extern spinlock_t modlist_lock;
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static inline unsigned long search_one_table(const struct exception_table_entry *first,
|
|
||||||
const struct exception_table_entry *last,
|
|
||||||
unsigned long value)
|
|
||||||
{
|
|
||||||
while (first <= last) {
|
|
||||||
const struct exception_table_entry __attribute__((aligned(8))) *mid;
|
|
||||||
long diff;
|
|
||||||
|
|
||||||
mid = (last - first) / 2 + first;
|
|
||||||
diff = mid->insn - value;
|
|
||||||
if (diff == 0)
|
|
||||||
return mid->fixup;
|
|
||||||
else if (diff < 0)
|
|
||||||
first = mid + 1;
|
|
||||||
else
|
|
||||||
last = mid - 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} /* end search_one_table() */
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -56,7 +56,6 @@ struct thread_info {
|
||||||
* used for syscalls somehow;
|
* used for syscalls somehow;
|
||||||
* seems to have a function pointer and four arguments
|
* seems to have a function pointer and four arguments
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
/* Points to the current pt_regs frame */
|
/* Points to the current pt_regs frame */
|
||||||
struct pt_regs *regs;
|
struct pt_regs *regs;
|
||||||
/*
|
/*
|
||||||
|
@ -83,9 +82,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = 1, \
|
.preempt_count = 1, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
.sp = 0, \
|
.sp = 0, \
|
||||||
.regs = NULL, \
|
.regs = NULL, \
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ asmlinkage int sys_rt_sigreturn(void)
|
||||||
sigset_t blocked;
|
sigset_t blocked;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
frame = (struct rt_sigframe __user *)pt_psp(regs);
|
frame = (struct rt_sigframe __user *)pt_psp(regs);
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
|
|
|
@ -27,7 +27,6 @@ struct thread_info {
|
||||||
__u32 status; /* Thread synchronous flags */
|
__u32 status; /* Thread synchronous flags */
|
||||||
mm_segment_t addr_limit; /* user-level address space limit */
|
mm_segment_t addr_limit; /* user-level address space limit */
|
||||||
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
||||||
struct restart_block restart_block;
|
|
||||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||||
__u64 ac_stamp;
|
__u64 ac_stamp;
|
||||||
__u64 ac_leave;
|
__u64 ac_leave;
|
||||||
|
@ -46,9 +45,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ASM_OFFSETS_C
|
#ifndef ASM_OFFSETS_C
|
||||||
|
|
|
@ -46,7 +46,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
|
||||||
long err;
|
long err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* restore scratch that always needs gets updated during signal delivery: */
|
/* restore scratch that always needs gets updated during signal delivery: */
|
||||||
err = __get_user(flags, &sc->sc_flags);
|
err = __get_user(flags, &sc->sc_flags);
|
||||||
|
|
|
@ -34,7 +34,6 @@ struct thread_info {
|
||||||
0-0xBFFFFFFF for user-thread
|
0-0xBFFFFFFF for user-thread
|
||||||
0-0xFFFFFFFF for kernel-thread
|
0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
};
|
};
|
||||||
|
@ -49,7 +48,6 @@ struct thread_info {
|
||||||
#define TI_CPU 0x00000010
|
#define TI_CPU 0x00000010
|
||||||
#define TI_PRE_COUNT 0x00000014
|
#define TI_PRE_COUNT 0x00000014
|
||||||
#define TI_ADDR_LIMIT 0x00000018
|
#define TI_ADDR_LIMIT 0x00000018
|
||||||
#define TI_RESTART_BLOCK 0x000001C
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -68,9 +66,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -48,7 +48,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
|
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
|
||||||
COPY(r4);
|
COPY(r4);
|
||||||
|
|
|
@ -31,7 +31,6 @@ struct thread_info {
|
||||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||||
__u32 cpu; /* should always be 0 on m68k */
|
__u32 cpu; /* should always be 0 on m68k */
|
||||||
unsigned long tp_value; /* thread pointer */
|
unsigned long tp_value; /* thread pointer */
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
@ -41,9 +40,6 @@ struct thread_info {
|
||||||
.exec_domain = &default_exec_domain, \
|
.exec_domain = &default_exec_domain, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_stack (init_thread_union.stack)
|
#define init_stack (init_thread_union.stack)
|
||||||
|
|
|
@ -655,7 +655,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* get previous context */
|
/* get previous context */
|
||||||
if (copy_from_user(&context, usc, sizeof(context)))
|
if (copy_from_user(&context, usc, sizeof(context)))
|
||||||
|
@ -693,7 +693,7 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
err = __get_user(temp, &uc->uc_mcontext.version);
|
err = __get_user(temp, &uc->uc_mcontext.version);
|
||||||
if (temp != MCONTEXT_VERSION)
|
if (temp != MCONTEXT_VERSION)
|
||||||
|
|
|
@ -35,9 +35,8 @@ struct thread_info {
|
||||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||||
|
|
||||||
mm_segment_t addr_limit; /* thread address space */
|
mm_segment_t addr_limit; /* thread address space */
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
u8 supervisor_stack[0];
|
u8 supervisor_stack[0] __aligned(8);
|
||||||
};
|
};
|
||||||
|
|
||||||
#else /* !__ASSEMBLY__ */
|
#else /* !__ASSEMBLY__ */
|
||||||
|
@ -74,9 +73,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -48,7 +48,7 @@ static int restore_sigcontext(struct pt_regs *regs,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
err = metag_gp_regs_copyin(regs, 0, sizeof(struct user_gp_regs), NULL,
|
err = metag_gp_regs_copyin(regs, 0, sizeof(struct user_gp_regs), NULL,
|
||||||
&sc->regs);
|
&sc->regs);
|
||||||
|
|
|
@ -71,7 +71,6 @@ struct thread_info {
|
||||||
__u32 cpu; /* current CPU */
|
__u32 cpu; /* current CPU */
|
||||||
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
|
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
|
||||||
mm_segment_t addr_limit; /* thread address space */
|
mm_segment_t addr_limit; /* thread address space */
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
struct cpu_context cpu_context;
|
struct cpu_context cpu_context;
|
||||||
};
|
};
|
||||||
|
@ -87,9 +86,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -89,7 +89,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
|
@ -34,7 +34,6 @@ struct thread_info {
|
||||||
* 0x7fffffff for user-thead
|
* 0x7fffffff for user-thead
|
||||||
* 0xffffffff for kernel-thread
|
* 0xffffffff for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
struct pt_regs *regs;
|
struct pt_regs *regs;
|
||||||
long syscall; /* syscall number */
|
long syscall; /* syscall number */
|
||||||
};
|
};
|
||||||
|
@ -50,9 +49,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -98,7 +98,6 @@ void output_thread_info_defines(void)
|
||||||
OFFSET(TI_CPU, thread_info, cpu);
|
OFFSET(TI_CPU, thread_info, cpu);
|
||||||
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
||||||
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
||||||
OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
|
|
||||||
OFFSET(TI_REGS, thread_info, regs);
|
OFFSET(TI_REGS, thread_info, regs);
|
||||||
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||||||
DEFINE(_THREAD_MASK, THREAD_MASK);
|
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||||||
|
|
|
@ -243,7 +243,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ static int restore_sigcontext32(struct pt_regs *regs,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
||||||
|
|
|
@ -50,7 +50,6 @@ struct thread_info {
|
||||||
0-0xBFFFFFFF for user-thead
|
0-0xBFFFFFFF for user-thead
|
||||||
0-0xFFFFFFFF for kernel-thread
|
0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
};
|
};
|
||||||
|
@ -80,9 +79,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -28,7 +28,6 @@ void foo(void)
|
||||||
OFFSET(TI_cpu, thread_info, cpu);
|
OFFSET(TI_cpu, thread_info, cpu);
|
||||||
OFFSET(TI_preempt_count, thread_info, preempt_count);
|
OFFSET(TI_preempt_count, thread_info, preempt_count);
|
||||||
OFFSET(TI_addr_limit, thread_info, addr_limit);
|
OFFSET(TI_addr_limit, thread_info, addr_limit);
|
||||||
OFFSET(TI_restart_block, thread_info, restart_block);
|
|
||||||
BLANK();
|
BLANK();
|
||||||
|
|
||||||
OFFSET(REG_D0, pt_regs, d0);
|
OFFSET(REG_D0, pt_regs, d0);
|
||||||
|
|
|
@ -40,7 +40,7 @@ static int restore_sigcontext(struct pt_regs *regs,
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (is_using_fpu(current))
|
if (is_using_fpu(current))
|
||||||
fpu_kill_state(current);
|
fpu_kill_state(current);
|
||||||
|
|
|
@ -57,7 +57,6 @@ struct thread_info {
|
||||||
0-0x7FFFFFFF for user-thead
|
0-0x7FFFFFFF for user-thead
|
||||||
0-0xFFFFFFFF for kernel-thread
|
0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
struct restart_block restart_block;
|
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
|
|
||||||
/* saved context data */
|
/* saved context data */
|
||||||
|
@ -79,9 +78,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = 1, \
|
.preempt_count = 1, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
.ksp = 0, \
|
.ksp = 0, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ static int restore_sigcontext(struct pt_regs *regs,
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore the regs from &sc->regs.
|
* Restore the regs from &sc->regs.
|
||||||
|
|
|
@ -14,7 +14,6 @@ struct thread_info {
|
||||||
mm_segment_t addr_limit; /* user-level address space limit */
|
mm_segment_t addr_limit; /* user-level address space limit */
|
||||||
__u32 cpu; /* current CPU */
|
__u32 cpu; /* current CPU */
|
||||||
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_THREAD_INFO(tsk) \
|
#define INIT_THREAD_INFO(tsk) \
|
||||||
|
@ -25,9 +24,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -99,7 +99,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* Unwind the user stack to get the rt_sigframe structure. */
|
/* Unwind the user stack to get the rt_sigframe structure. */
|
||||||
frame = (struct rt_sigframe __user *)
|
frame = (struct rt_sigframe __user *)
|
||||||
|
|
|
@ -40,63 +40,27 @@ static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK)
|
||||||
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
|
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
#ifdef CONFIG_NUMA_BALANCING
|
||||||
static inline int pte_present(pte_t pte)
|
|
||||||
{
|
|
||||||
return pte_val(pte) & _PAGE_NUMA_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define pte_present_nonuma pte_present_nonuma
|
|
||||||
static inline int pte_present_nonuma(pte_t pte)
|
|
||||||
{
|
|
||||||
return pte_val(pte) & (_PAGE_PRESENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ptep_set_numa ptep_set_numa
|
|
||||||
static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr,
|
|
||||||
pte_t *ptep)
|
|
||||||
{
|
|
||||||
if ((pte_val(*ptep) & _PAGE_PRESENT) == 0)
|
|
||||||
VM_BUG_ON(1);
|
|
||||||
|
|
||||||
pte_update(mm, addr, ptep, _PAGE_PRESENT, _PAGE_NUMA, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define pmdp_set_numa pmdp_set_numa
|
|
||||||
static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr,
|
|
||||||
pmd_t *pmdp)
|
|
||||||
{
|
|
||||||
if ((pmd_val(*pmdp) & _PAGE_PRESENT) == 0)
|
|
||||||
VM_BUG_ON(1);
|
|
||||||
|
|
||||||
pmd_hugepage_update(mm, addr, pmdp, _PAGE_PRESENT, _PAGE_NUMA);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic NUMA pte helpers expect pteval_t and pmdval_t types to exist
|
* These work without NUMA balancing but the kernel does not care. See the
|
||||||
* which was inherited from x86. For the purposes of powerpc pte_basic_t and
|
* comment in include/asm-generic/pgtable.h . On powerpc, this will only
|
||||||
* pmd_t are equivalent
|
* work for user pages and always return true for kernel pages.
|
||||||
*/
|
*/
|
||||||
#define pteval_t pte_basic_t
|
static inline int pte_protnone(pte_t pte)
|
||||||
#define pmdval_t pmd_t
|
|
||||||
static inline pteval_t ptenuma_flags(pte_t pte)
|
|
||||||
{
|
{
|
||||||
return pte_val(pte) & _PAGE_NUMA_MASK;
|
return (pte_val(pte) &
|
||||||
|
(_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pmdval_t pmdnuma_flags(pmd_t pmd)
|
static inline int pmd_protnone(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return pmd_val(pmd) & _PAGE_NUMA_MASK;
|
return pte_protnone(pmd_pte(pmd));
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_NUMA_BALANCING */
|
||||||
# else
|
|
||||||
|
|
||||||
static inline int pte_present(pte_t pte)
|
static inline int pte_present(pte_t pte)
|
||||||
{
|
{
|
||||||
return pte_val(pte) & _PAGE_PRESENT;
|
return pte_val(pte) & _PAGE_PRESENT;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NUMA_BALANCING */
|
|
||||||
|
|
||||||
/* Conversion functions: convert a page and protection to a page entry,
|
/* Conversion functions: convert a page and protection to a page entry,
|
||||||
* and a page entry and page directory to the page they refer to.
|
* and a page entry and page directory to the page they refer to.
|
||||||
|
|
|
@ -104,11 +104,6 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
|
||||||
_PAGE_USER | _PAGE_ACCESSED | _PAGE_RO | \
|
_PAGE_USER | _PAGE_ACCESSED | _PAGE_RO | \
|
||||||
_PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
|
_PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
|
||||||
/* Mask of bits that distinguish present and numa ptes */
|
|
||||||
#define _PAGE_NUMA_MASK (_PAGE_NUMA|_PAGE_PRESENT)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We define 2 sets of base prot bits, one for basic pages (ie,
|
* We define 2 sets of base prot bits, one for basic pages (ie,
|
||||||
* cacheable kernel and user pages) and one for non cacheable
|
* cacheable kernel and user pages) and one for non cacheable
|
||||||
|
|
|
@ -27,12 +27,6 @@
|
||||||
#define _PAGE_RW 0x0200 /* software: user write access allowed */
|
#define _PAGE_RW 0x0200 /* software: user write access allowed */
|
||||||
#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
|
#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
|
||||||
|
|
||||||
/*
|
|
||||||
* Used for tracking numa faults
|
|
||||||
*/
|
|
||||||
#define _PAGE_NUMA 0x00000010 /* Gather numa placement stats */
|
|
||||||
|
|
||||||
|
|
||||||
/* No separate kernel read-only */
|
/* No separate kernel read-only */
|
||||||
#define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
|
#define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
|
||||||
#define _PAGE_KERNEL_RO _PAGE_KERNEL_RW
|
#define _PAGE_KERNEL_RO _PAGE_KERNEL_RW
|
||||||
|
|
|
@ -43,7 +43,6 @@ struct thread_info {
|
||||||
int cpu; /* cpu we're on */
|
int cpu; /* cpu we're on */
|
||||||
int preempt_count; /* 0 => preemptable,
|
int preempt_count; /* 0 => preemptable,
|
||||||
<0 => BUG */
|
<0 => BUG */
|
||||||
struct restart_block restart_block;
|
|
||||||
unsigned long local_flags; /* private flags for thread */
|
unsigned long local_flags; /* private flags for thread */
|
||||||
|
|
||||||
/* low level flags - has atomic operations done on it */
|
/* low level flags - has atomic operations done on it */
|
||||||
|
@ -59,9 +58,6 @@ struct thread_info {
|
||||||
.exec_domain = &default_exec_domain, \
|
.exec_domain = &default_exec_domain, \
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1231,7 +1231,7 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
|
||||||
int tm_restore = 0;
|
int tm_restore = 0;
|
||||||
#endif
|
#endif
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
rt_sf = (struct rt_sigframe __user *)
|
rt_sf = (struct rt_sigframe __user *)
|
||||||
(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
|
(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
|
||||||
|
@ -1504,7 +1504,7 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
|
sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
|
||||||
sc = &sf->sctx;
|
sc = &sf->sctx;
|
||||||
|
|
|
@ -666,7 +666,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
|
if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
|
@ -621,6 +621,38 @@ unsigned long long sched_clock(void)
|
||||||
return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
|
return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Running clock - attempts to give a view of time passing for a virtualised
|
||||||
|
* kernels.
|
||||||
|
* Uses the VTB register if available otherwise a next best guess.
|
||||||
|
*/
|
||||||
|
unsigned long long running_clock(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Don't read the VTB as a host since KVM does not switch in host
|
||||||
|
* timebase into the VTB when it takes a guest off the CPU, reading the
|
||||||
|
* VTB would result in reading 'last switched out' guest VTB.
|
||||||
|
*
|
||||||
|
* Host kernels are often compiled with CONFIG_PPC_PSERIES checked, it
|
||||||
|
* would be unsafe to rely only on the #ifdef above.
|
||||||
|
*/
|
||||||
|
if (firmware_has_feature(FW_FEATURE_LPAR) &&
|
||||||
|
cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||||
|
return mulhdu(get_vtb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a next best approximation without a VTB.
|
||||||
|
* On a host which is running bare metal there should never be any stolen
|
||||||
|
* time and on a host which doesn't do any virtualisation TB *should* equal
|
||||||
|
* VTB so it makes no difference anyway.
|
||||||
|
*/
|
||||||
|
return local_clock() - cputime_to_nsecs(kcpustat_this_cpu->cpustat[CPUTIME_STEAL]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init get_freq(char *name, int cells, unsigned long *val)
|
static int __init get_freq(char *name, int cells, unsigned long *val)
|
||||||
{
|
{
|
||||||
struct device_node *cpu;
|
struct device_node *cpu;
|
||||||
|
|
|
@ -212,7 +212,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
|
||||||
/* Look up the Linux PTE for the backing page */
|
/* Look up the Linux PTE for the backing page */
|
||||||
pte_size = psize;
|
pte_size = psize;
|
||||||
pte = lookup_linux_pte_and_update(pgdir, hva, writing, &pte_size);
|
pte = lookup_linux_pte_and_update(pgdir, hva, writing, &pte_size);
|
||||||
if (pte_present(pte) && !pte_numa(pte)) {
|
if (pte_present(pte) && !pte_protnone(pte)) {
|
||||||
if (writing && !pte_write(pte))
|
if (writing && !pte_write(pte))
|
||||||
/* make the actual HPTE be read-only */
|
/* make the actual HPTE be read-only */
|
||||||
ptel = hpte_make_readonly(ptel);
|
ptel = hpte_make_readonly(ptel);
|
||||||
|
|
|
@ -64,10 +64,14 @@ int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
|
||||||
if (!(vma->vm_flags & VM_WRITE))
|
if (!(vma->vm_flags & VM_WRITE))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
} else {
|
} else {
|
||||||
if (dsisr & DSISR_PROTFAULT)
|
|
||||||
goto out_unlock;
|
|
||||||
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
/*
|
||||||
|
* protfault should only happen due to us
|
||||||
|
* mapping a region readonly temporarily. PROT_NONE
|
||||||
|
* is also covered by the VMA check above.
|
||||||
|
*/
|
||||||
|
WARN_ON_ONCE(dsisr & DSISR_PROTFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
|
@ -389,19 +389,6 @@ good_area:
|
||||||
#endif /* CONFIG_8xx */
|
#endif /* CONFIG_8xx */
|
||||||
|
|
||||||
if (is_exec) {
|
if (is_exec) {
|
||||||
#ifdef CONFIG_PPC_STD_MMU
|
|
||||||
/* Protection fault on exec go straight to failure on
|
|
||||||
* Hash based MMUs as they either don't support per-page
|
|
||||||
* execute permission, or if they do, it's handled already
|
|
||||||
* at the hash level. This test would probably have to
|
|
||||||
* be removed if we change the way this works to make hash
|
|
||||||
* processors use the same I/D cache coherency mechanism
|
|
||||||
* as embedded.
|
|
||||||
*/
|
|
||||||
if (error_code & DSISR_PROTFAULT)
|
|
||||||
goto bad_area;
|
|
||||||
#endif /* CONFIG_PPC_STD_MMU */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow execution from readable areas if the MMU does not
|
* Allow execution from readable areas if the MMU does not
|
||||||
* provide separate controls over reading and executing.
|
* provide separate controls over reading and executing.
|
||||||
|
@ -416,6 +403,14 @@ good_area:
|
||||||
(cpu_has_feature(CPU_FTR_NOEXECUTE) ||
|
(cpu_has_feature(CPU_FTR_NOEXECUTE) ||
|
||||||
!(vma->vm_flags & (VM_READ | VM_WRITE))))
|
!(vma->vm_flags & (VM_READ | VM_WRITE))))
|
||||||
goto bad_area;
|
goto bad_area;
|
||||||
|
#ifdef CONFIG_PPC_STD_MMU
|
||||||
|
/*
|
||||||
|
* protfault should only happen due to us
|
||||||
|
* mapping a region readonly temporarily. PROT_NONE
|
||||||
|
* is also covered by the VMA check above.
|
||||||
|
*/
|
||||||
|
WARN_ON_ONCE(error_code & DSISR_PROTFAULT);
|
||||||
|
#endif /* CONFIG_PPC_STD_MMU */
|
||||||
/* a write */
|
/* a write */
|
||||||
} else if (is_write) {
|
} else if (is_write) {
|
||||||
if (!(vma->vm_flags & VM_WRITE))
|
if (!(vma->vm_flags & VM_WRITE))
|
||||||
|
@ -423,11 +418,9 @@ good_area:
|
||||||
flags |= FAULT_FLAG_WRITE;
|
flags |= FAULT_FLAG_WRITE;
|
||||||
/* a read */
|
/* a read */
|
||||||
} else {
|
} else {
|
||||||
/* protection fault */
|
|
||||||
if (error_code & 0x08000000)
|
|
||||||
goto bad_area;
|
|
||||||
if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
|
if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
|
||||||
goto bad_area;
|
goto bad_area;
|
||||||
|
WARN_ON_ONCE(error_code & DSISR_PROTFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -172,9 +172,14 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
|
||||||
void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
|
void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
|
||||||
pte_t pte)
|
pte_t pte)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DEBUG_VM
|
/*
|
||||||
WARN_ON(pte_val(*ptep) & _PAGE_PRESENT);
|
* When handling numa faults, we already have the pte marked
|
||||||
#endif
|
* _PAGE_PRESENT, but we can be sure that it is not in hpte.
|
||||||
|
* Hence we can use set_pte_at for them.
|
||||||
|
*/
|
||||||
|
VM_WARN_ON((pte_val(*ptep) & (_PAGE_PRESENT | _PAGE_USER)) ==
|
||||||
|
(_PAGE_PRESENT | _PAGE_USER));
|
||||||
|
|
||||||
/* Note: mm->context.id might not yet have been assigned as
|
/* Note: mm->context.id might not yet have been assigned as
|
||||||
* this context might not have been activated yet when this
|
* this context might not have been activated yet when this
|
||||||
* is called.
|
* is called.
|
||||||
|
|
|
@ -718,7 +718,8 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
||||||
pmd_t *pmdp, pmd_t pmd)
|
pmd_t *pmdp, pmd_t pmd)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DEBUG_VM
|
#ifdef CONFIG_DEBUG_VM
|
||||||
WARN_ON(pmd_val(*pmdp) & _PAGE_PRESENT);
|
WARN_ON((pmd_val(*pmdp) & (_PAGE_PRESENT | _PAGE_USER)) ==
|
||||||
|
(_PAGE_PRESENT | _PAGE_USER));
|
||||||
assert_spin_locked(&mm->page_table_lock);
|
assert_spin_locked(&mm->page_table_lock);
|
||||||
WARN_ON(!pmd_trans_huge(pmd));
|
WARN_ON(!pmd_trans_huge(pmd));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,7 +44,6 @@ extern char *strstr(const char *, const char *);
|
||||||
#undef __HAVE_ARCH_STRCHR
|
#undef __HAVE_ARCH_STRCHR
|
||||||
#undef __HAVE_ARCH_STRNCHR
|
#undef __HAVE_ARCH_STRNCHR
|
||||||
#undef __HAVE_ARCH_STRNCMP
|
#undef __HAVE_ARCH_STRNCMP
|
||||||
#undef __HAVE_ARCH_STRNICMP
|
|
||||||
#undef __HAVE_ARCH_STRPBRK
|
#undef __HAVE_ARCH_STRPBRK
|
||||||
#undef __HAVE_ARCH_STRSEP
|
#undef __HAVE_ARCH_STRSEP
|
||||||
#undef __HAVE_ARCH_STRSPN
|
#undef __HAVE_ARCH_STRSPN
|
||||||
|
|
|
@ -39,7 +39,6 @@ struct thread_info {
|
||||||
unsigned long sys_call_table; /* System call table address */
|
unsigned long sys_call_table; /* System call table address */
|
||||||
unsigned int cpu; /* current CPU */
|
unsigned int cpu; /* current CPU */
|
||||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||||
struct restart_block restart_block;
|
|
||||||
unsigned int system_call;
|
unsigned int system_call;
|
||||||
__u64 user_timer;
|
__u64 user_timer;
|
||||||
__u64 system_timer;
|
__u64 system_timer;
|
||||||
|
@ -56,9 +55,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -209,7 +209,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Alwys make any pending restarted system call return -EINTR */
|
/* Alwys make any pending restarted system call return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
|
if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
|
@ -162,7 +162,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
||||||
_sigregs user_sregs;
|
_sigregs user_sregs;
|
||||||
|
|
||||||
/* Alwys make any pending restarted system call return -EINTR */
|
/* Alwys make any pending restarted system call return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs)))
|
if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
|
@ -42,7 +42,6 @@ struct thread_info {
|
||||||
* 0-0xFFFFFFFF for kernel-thread
|
* 0-0xFFFFFFFF for kernel-thread
|
||||||
*/
|
*/
|
||||||
mm_segment_t addr_limit;
|
mm_segment_t addr_limit;
|
||||||
struct restart_block restart_block;
|
|
||||||
struct pt_regs *regs;
|
struct pt_regs *regs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,9 +57,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = 1, \
|
.preempt_count = 1, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -106,7 +106,6 @@ void output_thread_info_defines(void)
|
||||||
OFFSET(TI_CPU, thread_info, cpu);
|
OFFSET(TI_CPU, thread_info, cpu);
|
||||||
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
||||||
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
|
||||||
OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
|
|
||||||
OFFSET(TI_REGS, thread_info, regs);
|
OFFSET(TI_REGS, thread_info, regs);
|
||||||
DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
|
DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
|
||||||
DEFINE(KERNEL_STACK_MASK, THREAD_MASK);
|
DEFINE(KERNEL_STACK_MASK, THREAD_MASK);
|
||||||
|
|
|
@ -141,7 +141,7 @@ score_rt_sigreturn(struct pt_regs *regs)
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
frame = (struct rt_sigframe __user *) regs->regs[0];
|
frame = (struct rt_sigframe __user *) regs->regs[0];
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
|
|
|
@ -33,7 +33,6 @@ struct thread_info {
|
||||||
__u32 cpu;
|
__u32 cpu;
|
||||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||||
mm_segment_t addr_limit; /* thread address space */
|
mm_segment_t addr_limit; /* thread address space */
|
||||||
struct restart_block restart_block;
|
|
||||||
unsigned long previous_sp; /* sp of previous stack in case
|
unsigned long previous_sp; /* sp of previous stack in case
|
||||||
of nested IRQ stacks */
|
of nested IRQ stacks */
|
||||||
__u8 supervisor_stack[0];
|
__u8 supervisor_stack[0];
|
||||||
|
@ -63,9 +62,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -25,7 +25,6 @@ int main(void)
|
||||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
||||||
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
|
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
|
||||||
DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
|
|
||||||
DEFINE(TI_SIZE, sizeof(struct thread_info));
|
DEFINE(TI_SIZE, sizeof(struct thread_info));
|
||||||
|
|
||||||
#ifdef CONFIG_HIBERNATION
|
#ifdef CONFIG_HIBERNATION
|
||||||
|
|
|
@ -156,7 +156,7 @@ asmlinkage int sys_sigreturn(void)
|
||||||
int r0;
|
int r0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
@ -186,7 +186,7 @@ asmlinkage int sys_rt_sigreturn(void)
|
||||||
int r0;
|
int r0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
|
@ -260,7 +260,7 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
|
||||||
long long ret;
|
long long ret;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
@ -294,7 +294,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
|
||||||
long long ret;
|
long long ret;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
|
@ -47,8 +47,6 @@ struct thread_info {
|
||||||
struct reg_window32 reg_window[NSWINS]; /* align for ldd! */
|
struct reg_window32 reg_window[NSWINS]; /* align for ldd! */
|
||||||
unsigned long rwbuf_stkptrs[NSWINS];
|
unsigned long rwbuf_stkptrs[NSWINS];
|
||||||
unsigned long w_saved;
|
unsigned long w_saved;
|
||||||
|
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -62,9 +60,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
@ -103,7 +98,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
|
||||||
#define TI_REG_WINDOW 0x30
|
#define TI_REG_WINDOW 0x30
|
||||||
#define TI_RWIN_SPTRS 0x230
|
#define TI_RWIN_SPTRS 0x230
|
||||||
#define TI_W_SAVED 0x250
|
#define TI_W_SAVED 0x250
|
||||||
/* #define TI_RESTART_BLOCK 0x25n */ /* Nobody cares */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* thread information flag bit numbers
|
* thread information flag bit numbers
|
||||||
|
|
|
@ -58,8 +58,6 @@ struct thread_info {
|
||||||
unsigned long gsr[7];
|
unsigned long gsr[7];
|
||||||
unsigned long xfsr[7];
|
unsigned long xfsr[7];
|
||||||
|
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
struct pt_regs *kern_una_regs;
|
struct pt_regs *kern_una_regs;
|
||||||
unsigned int kern_una_insn;
|
unsigned int kern_una_insn;
|
||||||
|
|
||||||
|
@ -92,10 +90,9 @@ struct thread_info {
|
||||||
#define TI_RWIN_SPTRS 0x000003c8
|
#define TI_RWIN_SPTRS 0x000003c8
|
||||||
#define TI_GSR 0x00000400
|
#define TI_GSR 0x00000400
|
||||||
#define TI_XFSR 0x00000438
|
#define TI_XFSR 0x00000438
|
||||||
#define TI_RESTART_BLOCK 0x00000470
|
#define TI_KUNA_REGS 0x00000470
|
||||||
#define TI_KUNA_REGS 0x000004a0
|
#define TI_KUNA_INSN 0x00000478
|
||||||
#define TI_KUNA_INSN 0x000004a8
|
#define TI_FPREGS 0x00000480
|
||||||
#define TI_FPREGS 0x000004c0
|
|
||||||
|
|
||||||
/* We embed this in the uppermost byte of thread_info->flags */
|
/* We embed this in the uppermost byte of thread_info->flags */
|
||||||
#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */
|
#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */
|
||||||
|
@ -124,9 +121,6 @@ struct thread_info {
|
||||||
.current_ds = ASI_P, \
|
.current_ds = ASI_P, \
|
||||||
.exec_domain = &default_exec_domain, \
|
.exec_domain = &default_exec_domain, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -150,7 +150,7 @@ void do_sigreturn32(struct pt_regs *regs)
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
synchronize_user_stack();
|
synchronize_user_stack();
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
synchronize_user_stack();
|
synchronize_user_stack();
|
||||||
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
|
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
|
||||||
|
|
|
@ -70,7 +70,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
synchronize_user_stack();
|
synchronize_user_stack();
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
synchronize_user_stack ();
|
synchronize_user_stack ();
|
||||||
sf = (struct rt_signal_frame __user *)
|
sf = (struct rt_signal_frame __user *)
|
||||||
|
|
|
@ -2730,8 +2730,6 @@ void __init trap_init(void)
|
||||||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
|
TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
|
||||||
TI_CURRENT_DS != offsetof(struct thread_info,
|
TI_CURRENT_DS != offsetof(struct thread_info,
|
||||||
current_ds) ||
|
current_ds) ||
|
||||||
TI_RESTART_BLOCK != offsetof(struct thread_info,
|
|
||||||
restart_block) ||
|
|
||||||
TI_KUNA_REGS != offsetof(struct thread_info,
|
TI_KUNA_REGS != offsetof(struct thread_info,
|
||||||
kern_una_regs) ||
|
kern_una_regs) ||
|
||||||
TI_KUNA_INSN != offsetof(struct thread_info,
|
TI_KUNA_INSN != offsetof(struct thread_info,
|
||||||
|
|
|
@ -36,7 +36,6 @@ struct thread_info {
|
||||||
|
|
||||||
mm_segment_t addr_limit; /* thread address space
|
mm_segment_t addr_limit; /* thread address space
|
||||||
(KERNEL_DS or USER_DS) */
|
(KERNEL_DS or USER_DS) */
|
||||||
struct restart_block restart_block;
|
|
||||||
struct single_step_state *step_state; /* single step state
|
struct single_step_state *step_state; /* single step state
|
||||||
(if non-zero) */
|
(if non-zero) */
|
||||||
int align_ctl; /* controls unaligned access */
|
int align_ctl; /* controls unaligned access */
|
||||||
|
@ -57,9 +56,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
.step_state = NULL, \
|
.step_state = NULL, \
|
||||||
.align_ctl = 0, \
|
.align_ctl = 0, \
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ int restore_sigcontext(struct pt_regs *regs,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enforce that sigcontext is like pt_regs, and doesn't mess
|
* Enforce that sigcontext is like pt_regs, and doesn't mess
|
||||||
|
|
|
@ -22,7 +22,6 @@ struct thread_info {
|
||||||
mm_segment_t addr_limit; /* thread address space:
|
mm_segment_t addr_limit; /* thread address space:
|
||||||
0-0xBFFFFFFF for user
|
0-0xBFFFFFFF for user
|
||||||
0-0xFFFFFFFF for kernel */
|
0-0xFFFFFFFF for kernel */
|
||||||
struct restart_block restart_block;
|
|
||||||
struct thread_info *real_thread; /* Points to non-IRQ stack */
|
struct thread_info *real_thread; /* Points to non-IRQ stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,9 +33,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
.real_thread = NULL, \
|
.real_thread = NULL, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ struct thread_info {
|
||||||
#ifdef CONFIG_UNICORE_FPU_F64
|
#ifdef CONFIG_UNICORE_FPU_F64
|
||||||
struct fp_state fpstate __attribute__((aligned(8)));
|
struct fp_state fpstate __attribute__((aligned(8)));
|
||||||
#endif
|
#endif
|
||||||
struct restart_block restart_block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_THREAD_INFO(tsk) \
|
#define INIT_THREAD_INFO(tsk) \
|
||||||
|
@ -89,9 +88,6 @@ struct thread_info {
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -105,7 +105,7 @@ asmlinkage int __sys_rt_sigreturn(struct pt_regs *regs)
|
||||||
struct rt_sigframe __user *frame;
|
struct rt_sigframe __user *frame;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we stacked the signal on a 64-bit boundary,
|
* Since we stacked the signal on a 64-bit boundary,
|
||||||
|
|
|
@ -169,7 +169,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
get_user_try {
|
get_user_try {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -132,13 +132,7 @@ static inline int pte_exec(pte_t pte)
|
||||||
|
|
||||||
static inline int pte_special(pte_t pte)
|
static inline int pte_special(pte_t pte)
|
||||||
{
|
{
|
||||||
/*
|
return pte_flags(pte) & _PAGE_SPECIAL;
|
||||||
* See CONFIG_NUMA_BALANCING pte_numa in include/asm-generic/pgtable.h.
|
|
||||||
* On x86 we have _PAGE_BIT_NUMA == _PAGE_BIT_GLOBAL+1 ==
|
|
||||||
* __PAGE_BIT_SOFTW1 == _PAGE_BIT_SPECIAL.
|
|
||||||
*/
|
|
||||||
return (pte_flags(pte) & _PAGE_SPECIAL) &&
|
|
||||||
(pte_flags(pte) & (_PAGE_PRESENT|_PAGE_PROTNONE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long pte_pfn(pte_t pte)
|
static inline unsigned long pte_pfn(pte_t pte)
|
||||||
|
@ -300,7 +294,7 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd)
|
||||||
|
|
||||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return pmd_clear_flags(pmd, _PAGE_PRESENT);
|
return pmd_clear_flags(pmd, _PAGE_PRESENT | _PAGE_PROTNONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
|
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
|
||||||
|
@ -442,13 +436,6 @@ static inline int pte_same(pte_t a, pte_t b)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pte_present(pte_t a)
|
static inline int pte_present(pte_t a)
|
||||||
{
|
|
||||||
return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE |
|
|
||||||
_PAGE_NUMA);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define pte_present_nonuma pte_present_nonuma
|
|
||||||
static inline int pte_present_nonuma(pte_t a)
|
|
||||||
{
|
{
|
||||||
return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
|
return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
|
||||||
}
|
}
|
||||||
|
@ -459,7 +446,7 @@ static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
|
||||||
if (pte_flags(a) & _PAGE_PRESENT)
|
if (pte_flags(a) & _PAGE_PRESENT)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ((pte_flags(a) & (_PAGE_PROTNONE | _PAGE_NUMA)) &&
|
if ((pte_flags(a) & _PAGE_PROTNONE) &&
|
||||||
mm_tlb_flush_pending(mm))
|
mm_tlb_flush_pending(mm))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -479,10 +466,25 @@ static inline int pmd_present(pmd_t pmd)
|
||||||
* the _PAGE_PSE flag will remain set at all times while the
|
* the _PAGE_PSE flag will remain set at all times while the
|
||||||
* _PAGE_PRESENT bit is clear).
|
* _PAGE_PRESENT bit is clear).
|
||||||
*/
|
*/
|
||||||
return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE |
|
return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE);
|
||||||
_PAGE_NUMA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA_BALANCING
|
||||||
|
/*
|
||||||
|
* These work without NUMA balancing but the kernel does not care. See the
|
||||||
|
* comment in include/asm-generic/pgtable.h
|
||||||
|
*/
|
||||||
|
static inline int pte_protnone(pte_t pte)
|
||||||
|
{
|
||||||
|
return pte_flags(pte) & _PAGE_PROTNONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pmd_protnone(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return pmd_flags(pmd) & _PAGE_PROTNONE;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NUMA_BALANCING */
|
||||||
|
|
||||||
static inline int pmd_none(pmd_t pmd)
|
static inline int pmd_none(pmd_t pmd)
|
||||||
{
|
{
|
||||||
/* Only check low word on 32-bit platforms, since it might be
|
/* Only check low word on 32-bit platforms, since it might be
|
||||||
|
@ -539,11 +541,6 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
|
||||||
|
|
||||||
static inline int pmd_bad(pmd_t pmd)
|
static inline int pmd_bad(pmd_t pmd)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
|
||||||
/* pmd_numa check */
|
|
||||||
if ((pmd_flags(pmd) & (_PAGE_NUMA|_PAGE_PRESENT)) == _PAGE_NUMA)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
|
return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,19 +859,16 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
|
||||||
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
|
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
|
||||||
static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
|
static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
|
||||||
{
|
{
|
||||||
VM_BUG_ON(pte_present_nonuma(pte));
|
|
||||||
return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY);
|
return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pte_swp_soft_dirty(pte_t pte)
|
static inline int pte_swp_soft_dirty(pte_t pte)
|
||||||
{
|
{
|
||||||
VM_BUG_ON(pte_present_nonuma(pte));
|
|
||||||
return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY;
|
return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
|
static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
|
||||||
{
|
{
|
||||||
VM_BUG_ON(pte_present_nonuma(pte));
|
|
||||||
return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY);
|
return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -142,12 +142,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
|
||||||
|
|
||||||
/* Encode and de-code a swap entry */
|
/* Encode and de-code a swap entry */
|
||||||
#define SWP_TYPE_BITS 5
|
#define SWP_TYPE_BITS 5
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
|
||||||
/* Automatic NUMA balancing needs to be distinguishable from swap entries */
|
|
||||||
#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 2)
|
|
||||||
#else
|
|
||||||
#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1)
|
#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
|
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,6 @@
|
||||||
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
||||||
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
||||||
|
|
||||||
/*
|
|
||||||
* Swap offsets on configurations that allow automatic NUMA balancing use the
|
|
||||||
* bits after _PAGE_BIT_GLOBAL. To uniquely distinguish NUMA hinting PTEs from
|
|
||||||
* swap entries, we use the first bit after _PAGE_BIT_GLOBAL and shrink the
|
|
||||||
* maximum possible swap space from 16TB to 8TB.
|
|
||||||
*/
|
|
||||||
#define _PAGE_BIT_NUMA (_PAGE_BIT_GLOBAL+1)
|
|
||||||
|
|
||||||
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
||||||
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
||||||
#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
|
#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
|
||||||
|
@ -75,21 +67,6 @@
|
||||||
#define _PAGE_SOFT_DIRTY (_AT(pteval_t, 0))
|
#define _PAGE_SOFT_DIRTY (_AT(pteval_t, 0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* _PAGE_NUMA distinguishes between a numa hinting minor fault and a page
|
|
||||||
* that is not present. The hinting fault gathers numa placement statistics
|
|
||||||
* (see pte_numa()). The bit is always zero when the PTE is not present.
|
|
||||||
*
|
|
||||||
* The bit picked must be always zero when the pmd is present and not
|
|
||||||
* present, so that we don't lose information when we set it while
|
|
||||||
* atomically clearing the present bit.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
|
||||||
#define _PAGE_NUMA (_AT(pteval_t, 1) << _PAGE_BIT_NUMA)
|
|
||||||
#else
|
|
||||||
#define _PAGE_NUMA (_AT(pteval_t, 0))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tracking soft dirty bit when a page goes to a swap is tricky.
|
* Tracking soft dirty bit when a page goes to a swap is tricky.
|
||||||
* We need a bit which can be stored in pte _and_ not conflict
|
* We need a bit which can be stored in pte _and_ not conflict
|
||||||
|
@ -122,8 +99,8 @@
|
||||||
/* Set of bits not changed in pte_modify */
|
/* Set of bits not changed in pte_modify */
|
||||||
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
||||||
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
||||||
_PAGE_SOFT_DIRTY | _PAGE_NUMA)
|
_PAGE_SOFT_DIRTY)
|
||||||
#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_NUMA)
|
#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The cache modes defined here are used to translate between pure SW usage
|
* The cache modes defined here are used to translate between pure SW usage
|
||||||
|
@ -324,20 +301,6 @@ static inline pteval_t pte_flags(pte_t pte)
|
||||||
return native_pte_val(pte) & PTE_FLAGS_MASK;
|
return native_pte_val(pte) & PTE_FLAGS_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
|
||||||
/* Set of bits that distinguishes present, prot_none and numa ptes */
|
|
||||||
#define _PAGE_NUMA_MASK (_PAGE_NUMA|_PAGE_PROTNONE|_PAGE_PRESENT)
|
|
||||||
static inline pteval_t ptenuma_flags(pte_t pte)
|
|
||||||
{
|
|
||||||
return pte_flags(pte) & _PAGE_NUMA_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pmdval_t pmdnuma_flags(pmd_t pmd)
|
|
||||||
{
|
|
||||||
return pmd_flags(pmd) & _PAGE_NUMA_MASK;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NUMA_BALANCING */
|
|
||||||
|
|
||||||
#define pgprot_val(x) ((x).pgprot)
|
#define pgprot_val(x) ((x).pgprot)
|
||||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ struct thread_info {
|
||||||
__u32 cpu; /* current CPU */
|
__u32 cpu; /* current CPU */
|
||||||
int saved_preempt_count;
|
int saved_preempt_count;
|
||||||
mm_segment_t addr_limit;
|
mm_segment_t addr_limit;
|
||||||
struct restart_block restart_block;
|
|
||||||
void __user *sysenter_return;
|
void __user *sysenter_return;
|
||||||
unsigned int sig_on_uaccess_error:1;
|
unsigned int sig_on_uaccess_error:1;
|
||||||
unsigned int uaccess_err:1; /* uaccess failed */
|
unsigned int uaccess_err:1; /* uaccess failed */
|
||||||
|
@ -45,9 +44,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.saved_preempt_count = INIT_PREEMPT_COUNT, \
|
.saved_preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -168,7 +168,7 @@ static void _hpet_print_config(const char *function, int line)
|
||||||
#define hpet_print_config() \
|
#define hpet_print_config() \
|
||||||
do { \
|
do { \
|
||||||
if (hpet_verbose) \
|
if (hpet_verbose) \
|
||||||
_hpet_print_config(__FUNCTION__, __LINE__); \
|
_hpet_print_config(__func__, __LINE__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -49,11 +49,11 @@ int mach_set_rtc_mmss(const struct timespec *now)
|
||||||
retval = set_rtc_time(&tm);
|
retval = set_rtc_time(&tm);
|
||||||
if (retval)
|
if (retval)
|
||||||
printk(KERN_ERR "%s: RTC write failed with error %d\n",
|
printk(KERN_ERR "%s: RTC write failed with error %d\n",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"%s: Invalid RTC value: write of %lx to RTC failed\n",
|
"%s: Invalid RTC value: write of %lx to RTC failed\n",
|
||||||
__FUNCTION__, nowtime);
|
__func__, nowtime);
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -69,7 +69,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
get_user_try {
|
get_user_try {
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
/* Similar to the PMD case, NUMA hinting must take slow path */
|
/* Similar to the PMD case, NUMA hinting must take slow path */
|
||||||
if (pte_numa(pte)) {
|
if (pte_protnone(pte)) {
|
||||||
pte_unmap(ptep);
|
pte_unmap(ptep);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
|
||||||
* slowpath for accounting purposes and so that they
|
* slowpath for accounting purposes and so that they
|
||||||
* can be serialised against THP migration.
|
* can be serialised against THP migration.
|
||||||
*/
|
*/
|
||||||
if (pmd_numa(pmd))
|
if (pmd_protnone(pmd))
|
||||||
return 0;
|
return 0;
|
||||||
if (!gup_huge_pmd(pmd, addr, next, write, pages, nr))
|
if (!gup_huge_pmd(pmd, addr, next, write, pages, nr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -110,7 +110,7 @@ int vrtc_set_mmss(const struct timespec *now)
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
} else {
|
} else {
|
||||||
pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n",
|
pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n",
|
||||||
__FUNCTION__, now->tv_sec);
|
__func__, now->tv_sec);
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -157,7 +157,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
|
||||||
int err, pid;
|
int err, pid;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
err = copy_from_user(&sc, from, sizeof(sc));
|
err = copy_from_user(&sc, from, sizeof(sc));
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -51,7 +51,6 @@ struct thread_info {
|
||||||
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
|
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
|
||||||
|
|
||||||
mm_segment_t addr_limit; /* thread address space */
|
mm_segment_t addr_limit; /* thread address space */
|
||||||
struct restart_block restart_block;
|
|
||||||
|
|
||||||
unsigned long cpenable;
|
unsigned long cpenable;
|
||||||
|
|
||||||
|
@ -72,7 +71,6 @@ struct thread_info {
|
||||||
#define TI_CPU 0x00000010
|
#define TI_CPU 0x00000010
|
||||||
#define TI_PRE_COUNT 0x00000014
|
#define TI_PRE_COUNT 0x00000014
|
||||||
#define TI_ADDR_LIMIT 0x00000018
|
#define TI_ADDR_LIMIT 0x00000018
|
||||||
#define TI_RESTART_BLOCK 0x000001C
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -90,9 +88,6 @@ struct thread_info {
|
||||||
.cpu = 0, \
|
.cpu = 0, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
.addr_limit = KERNEL_DS, \
|
.addr_limit = KERNEL_DS, \
|
||||||
.restart_block = { \
|
|
||||||
.fn = do_no_restart_syscall, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_thread_info (init_thread_union.thread_info)
|
#define init_thread_info (init_thread_union.thread_info)
|
||||||
|
|
|
@ -245,7 +245,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
if (regs->depc > 64)
|
if (regs->depc > 64)
|
||||||
panic("rt_sigreturn in double exception!\n");
|
panic("rt_sigreturn in double exception!\n");
|
||||||
|
|
|
@ -111,8 +111,8 @@ void acpi_ut_track_stack_ptr(void)
|
||||||
* RETURN: Updated pointer to the function name
|
* RETURN: Updated pointer to the function name
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
|
* DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
|
||||||
* This allows compiler macros such as __FUNCTION__ to be used
|
* This allows compiler macros such as __func__ to be used with no
|
||||||
* with no change to the debug output.
|
* change to the debug output.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1391,7 +1391,7 @@ static int blkfront_probe(struct xenbus_device *dev,
|
||||||
if (major != XENVBD_MAJOR) {
|
if (major != XENVBD_MAJOR) {
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"%s: HVM does not support vbd %d as xen block device\n",
|
"%s: HVM does not support vbd %d as xen block device\n",
|
||||||
__FUNCTION__, vdevice);
|
__func__, vdevice);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,9 +53,9 @@ static ssize_t name##_show(struct device *d, \
|
||||||
} \
|
} \
|
||||||
static DEVICE_ATTR_RO(name);
|
static DEVICE_ATTR_RO(name);
|
||||||
|
|
||||||
static inline int init_done(struct zram *zram)
|
static inline bool init_done(struct zram *zram)
|
||||||
{
|
{
|
||||||
return zram->meta != NULL;
|
return zram->disksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct zram *dev_to_zram(struct device *dev)
|
static inline struct zram *dev_to_zram(struct device *dev)
|
||||||
|
@ -307,42 +307,67 @@ static inline int valid_io_request(struct zram *zram,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zram_meta_free(struct zram_meta *meta)
|
static void zram_meta_free(struct zram_meta *meta, u64 disksize)
|
||||||
{
|
{
|
||||||
|
size_t num_pages = disksize >> PAGE_SHIFT;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
/* Free all pages that are still in this zram device */
|
||||||
|
for (index = 0; index < num_pages; index++) {
|
||||||
|
unsigned long handle = meta->table[index].handle;
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zs_free(meta->mem_pool, handle);
|
||||||
|
}
|
||||||
|
|
||||||
zs_destroy_pool(meta->mem_pool);
|
zs_destroy_pool(meta->mem_pool);
|
||||||
vfree(meta->table);
|
vfree(meta->table);
|
||||||
kfree(meta);
|
kfree(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct zram_meta *zram_meta_alloc(u64 disksize)
|
static struct zram_meta *zram_meta_alloc(int device_id, u64 disksize)
|
||||||
{
|
{
|
||||||
size_t num_pages;
|
size_t num_pages;
|
||||||
|
char pool_name[8];
|
||||||
struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL);
|
struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL);
|
||||||
|
|
||||||
if (!meta)
|
if (!meta)
|
||||||
goto out;
|
return NULL;
|
||||||
|
|
||||||
num_pages = disksize >> PAGE_SHIFT;
|
num_pages = disksize >> PAGE_SHIFT;
|
||||||
meta->table = vzalloc(num_pages * sizeof(*meta->table));
|
meta->table = vzalloc(num_pages * sizeof(*meta->table));
|
||||||
if (!meta->table) {
|
if (!meta->table) {
|
||||||
pr_err("Error allocating zram address table\n");
|
pr_err("Error allocating zram address table\n");
|
||||||
goto free_meta;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta->mem_pool = zs_create_pool(GFP_NOIO | __GFP_HIGHMEM);
|
snprintf(pool_name, sizeof(pool_name), "zram%d", device_id);
|
||||||
|
meta->mem_pool = zs_create_pool(pool_name, GFP_NOIO | __GFP_HIGHMEM);
|
||||||
if (!meta->mem_pool) {
|
if (!meta->mem_pool) {
|
||||||
pr_err("Error creating memory pool\n");
|
pr_err("Error creating memory pool\n");
|
||||||
goto free_table;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return meta;
|
return meta;
|
||||||
|
|
||||||
free_table:
|
out_error:
|
||||||
vfree(meta->table);
|
vfree(meta->table);
|
||||||
free_meta:
|
|
||||||
kfree(meta);
|
kfree(meta);
|
||||||
meta = NULL;
|
return NULL;
|
||||||
out:
|
}
|
||||||
return meta;
|
|
||||||
|
static inline bool zram_meta_get(struct zram *zram)
|
||||||
|
{
|
||||||
|
if (atomic_inc_not_zero(&zram->refcount))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void zram_meta_put(struct zram *zram)
|
||||||
|
{
|
||||||
|
atomic_dec(&zram->refcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_position(u32 *index, int *offset, struct bio_vec *bvec)
|
static void update_position(u32 *index, int *offset, struct bio_vec *bvec)
|
||||||
|
@ -704,10 +729,11 @@ static void zram_bio_discard(struct zram *zram, u32 index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zram_reset_device(struct zram *zram, bool reset_capacity)
|
static void zram_reset_device(struct zram *zram)
|
||||||
{
|
{
|
||||||
size_t index;
|
|
||||||
struct zram_meta *meta;
|
struct zram_meta *meta;
|
||||||
|
struct zcomp *comp;
|
||||||
|
u64 disksize;
|
||||||
|
|
||||||
down_write(&zram->init_lock);
|
down_write(&zram->init_lock);
|
||||||
|
|
||||||
|
@ -719,36 +745,30 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
meta = zram->meta;
|
meta = zram->meta;
|
||||||
/* Free all pages that are still in this zram device */
|
comp = zram->comp;
|
||||||
for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {
|
disksize = zram->disksize;
|
||||||
unsigned long handle = meta->table[index].handle;
|
/*
|
||||||
if (!handle)
|
* Refcount will go down to 0 eventually and r/w handler
|
||||||
continue;
|
* cannot handle further I/O so it will bail out by
|
||||||
|
* check zram_meta_get.
|
||||||
|
*/
|
||||||
|
zram_meta_put(zram);
|
||||||
|
/*
|
||||||
|
* We want to free zram_meta in process context to avoid
|
||||||
|
* deadlock between reclaim path and any other locks.
|
||||||
|
*/
|
||||||
|
wait_event(zram->io_done, atomic_read(&zram->refcount) == 0);
|
||||||
|
|
||||||
zs_free(meta->mem_pool, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
zcomp_destroy(zram->comp);
|
|
||||||
zram->max_comp_streams = 1;
|
|
||||||
|
|
||||||
zram_meta_free(zram->meta);
|
|
||||||
zram->meta = NULL;
|
|
||||||
/* Reset stats */
|
/* Reset stats */
|
||||||
memset(&zram->stats, 0, sizeof(zram->stats));
|
memset(&zram->stats, 0, sizeof(zram->stats));
|
||||||
|
|
||||||
zram->disksize = 0;
|
zram->disksize = 0;
|
||||||
if (reset_capacity)
|
zram->max_comp_streams = 1;
|
||||||
set_capacity(zram->disk, 0);
|
set_capacity(zram->disk, 0);
|
||||||
|
|
||||||
up_write(&zram->init_lock);
|
up_write(&zram->init_lock);
|
||||||
|
/* I/O operation under all of CPU are done so let's free */
|
||||||
/*
|
zram_meta_free(meta, disksize);
|
||||||
* Revalidate disk out of the init_lock to avoid lockdep splat.
|
zcomp_destroy(comp);
|
||||||
* It's okay because disk's capacity is protected by init_lock
|
|
||||||
* so that revalidate_disk always sees up-to-date capacity.
|
|
||||||
*/
|
|
||||||
if (reset_capacity)
|
|
||||||
revalidate_disk(zram->disk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t disksize_store(struct device *dev,
|
static ssize_t disksize_store(struct device *dev,
|
||||||
|
@ -765,7 +785,7 @@ static ssize_t disksize_store(struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
disksize = PAGE_ALIGN(disksize);
|
disksize = PAGE_ALIGN(disksize);
|
||||||
meta = zram_meta_alloc(disksize);
|
meta = zram_meta_alloc(zram->disk->first_minor, disksize);
|
||||||
if (!meta)
|
if (!meta)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -784,6 +804,8 @@ static ssize_t disksize_store(struct device *dev,
|
||||||
goto out_destroy_comp;
|
goto out_destroy_comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_waitqueue_head(&zram->io_done);
|
||||||
|
atomic_set(&zram->refcount, 1);
|
||||||
zram->meta = meta;
|
zram->meta = meta;
|
||||||
zram->comp = comp;
|
zram->comp = comp;
|
||||||
zram->disksize = disksize;
|
zram->disksize = disksize;
|
||||||
|
@ -803,7 +825,7 @@ out_destroy_comp:
|
||||||
up_write(&zram->init_lock);
|
up_write(&zram->init_lock);
|
||||||
zcomp_destroy(comp);
|
zcomp_destroy(comp);
|
||||||
out_free_meta:
|
out_free_meta:
|
||||||
zram_meta_free(meta);
|
zram_meta_free(meta, disksize);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,8 +843,9 @@ static ssize_t reset_store(struct device *dev,
|
||||||
if (!bdev)
|
if (!bdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mutex_lock(&bdev->bd_mutex);
|
||||||
/* Do not reset an active device! */
|
/* Do not reset an active device! */
|
||||||
if (bdev->bd_holders) {
|
if (bdev->bd_openers) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -838,12 +861,16 @@ static ssize_t reset_store(struct device *dev,
|
||||||
|
|
||||||
/* Make sure all pending I/O is finished */
|
/* Make sure all pending I/O is finished */
|
||||||
fsync_bdev(bdev);
|
fsync_bdev(bdev);
|
||||||
|
zram_reset_device(zram);
|
||||||
|
|
||||||
|
mutex_unlock(&bdev->bd_mutex);
|
||||||
|
revalidate_disk(zram->disk);
|
||||||
bdput(bdev);
|
bdput(bdev);
|
||||||
|
|
||||||
zram_reset_device(zram, true);
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
mutex_unlock(&bdev->bd_mutex);
|
||||||
bdput(bdev);
|
bdput(bdev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -909,23 +936,21 @@ static void zram_make_request(struct request_queue *queue, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct zram *zram = queue->queuedata;
|
struct zram *zram = queue->queuedata;
|
||||||
|
|
||||||
down_read(&zram->init_lock);
|
if (unlikely(!zram_meta_get(zram)))
|
||||||
if (unlikely(!init_done(zram)))
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!valid_io_request(zram, bio->bi_iter.bi_sector,
|
if (!valid_io_request(zram, bio->bi_iter.bi_sector,
|
||||||
bio->bi_iter.bi_size)) {
|
bio->bi_iter.bi_size)) {
|
||||||
atomic64_inc(&zram->stats.invalid_io);
|
atomic64_inc(&zram->stats.invalid_io);
|
||||||
goto error;
|
goto put_zram;
|
||||||
}
|
}
|
||||||
|
|
||||||
__zram_make_request(zram, bio);
|
__zram_make_request(zram, bio);
|
||||||
up_read(&zram->init_lock);
|
zram_meta_put(zram);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
put_zram:
|
||||||
|
zram_meta_put(zram);
|
||||||
error:
|
error:
|
||||||
up_read(&zram->init_lock);
|
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,21 +972,19 @@ static void zram_slot_free_notify(struct block_device *bdev,
|
||||||
static int zram_rw_page(struct block_device *bdev, sector_t sector,
|
static int zram_rw_page(struct block_device *bdev, sector_t sector,
|
||||||
struct page *page, int rw)
|
struct page *page, int rw)
|
||||||
{
|
{
|
||||||
int offset, err;
|
int offset, err = -EIO;
|
||||||
u32 index;
|
u32 index;
|
||||||
struct zram *zram;
|
struct zram *zram;
|
||||||
struct bio_vec bv;
|
struct bio_vec bv;
|
||||||
|
|
||||||
zram = bdev->bd_disk->private_data;
|
zram = bdev->bd_disk->private_data;
|
||||||
|
if (unlikely(!zram_meta_get(zram)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (!valid_io_request(zram, sector, PAGE_SIZE)) {
|
if (!valid_io_request(zram, sector, PAGE_SIZE)) {
|
||||||
atomic64_inc(&zram->stats.invalid_io);
|
atomic64_inc(&zram->stats.invalid_io);
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
}
|
goto put_zram;
|
||||||
|
|
||||||
down_read(&zram->init_lock);
|
|
||||||
if (unlikely(!init_done(zram))) {
|
|
||||||
err = -EIO;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
index = sector >> SECTORS_PER_PAGE_SHIFT;
|
index = sector >> SECTORS_PER_PAGE_SHIFT;
|
||||||
|
@ -972,8 +995,9 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector,
|
||||||
bv.bv_offset = 0;
|
bv.bv_offset = 0;
|
||||||
|
|
||||||
err = zram_bvec_rw(zram, &bv, index, offset, rw);
|
err = zram_bvec_rw(zram, &bv, index, offset, rw);
|
||||||
out_unlock:
|
put_zram:
|
||||||
up_read(&zram->init_lock);
|
zram_meta_put(zram);
|
||||||
|
out:
|
||||||
/*
|
/*
|
||||||
* If I/O fails, just return error(ie, non-zero) without
|
* If I/O fails, just return error(ie, non-zero) without
|
||||||
* calling page_endio.
|
* calling page_endio.
|
||||||
|
@ -1039,19 +1063,19 @@ static struct attribute_group zram_disk_attr_group = {
|
||||||
|
|
||||||
static int create_device(struct zram *zram, int device_id)
|
static int create_device(struct zram *zram, int device_id)
|
||||||
{
|
{
|
||||||
|
struct request_queue *queue;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
init_rwsem(&zram->init_lock);
|
init_rwsem(&zram->init_lock);
|
||||||
|
|
||||||
zram->queue = blk_alloc_queue(GFP_KERNEL);
|
queue = blk_alloc_queue(GFP_KERNEL);
|
||||||
if (!zram->queue) {
|
if (!queue) {
|
||||||
pr_err("Error allocating disk queue for device %d\n",
|
pr_err("Error allocating disk queue for device %d\n",
|
||||||
device_id);
|
device_id);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
blk_queue_make_request(zram->queue, zram_make_request);
|
blk_queue_make_request(queue, zram_make_request);
|
||||||
zram->queue->queuedata = zram;
|
|
||||||
|
|
||||||
/* gendisk structure */
|
/* gendisk structure */
|
||||||
zram->disk = alloc_disk(1);
|
zram->disk = alloc_disk(1);
|
||||||
|
@ -1064,7 +1088,8 @@ static int create_device(struct zram *zram, int device_id)
|
||||||
zram->disk->major = zram_major;
|
zram->disk->major = zram_major;
|
||||||
zram->disk->first_minor = device_id;
|
zram->disk->first_minor = device_id;
|
||||||
zram->disk->fops = &zram_devops;
|
zram->disk->fops = &zram_devops;
|
||||||
zram->disk->queue = zram->queue;
|
zram->disk->queue = queue;
|
||||||
|
zram->disk->queue->queuedata = zram;
|
||||||
zram->disk->private_data = zram;
|
zram->disk->private_data = zram;
|
||||||
snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
|
snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
|
||||||
|
|
||||||
|
@ -1115,20 +1140,35 @@ out_free_disk:
|
||||||
del_gendisk(zram->disk);
|
del_gendisk(zram->disk);
|
||||||
put_disk(zram->disk);
|
put_disk(zram->disk);
|
||||||
out_free_queue:
|
out_free_queue:
|
||||||
blk_cleanup_queue(zram->queue);
|
blk_cleanup_queue(queue);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_device(struct zram *zram)
|
static void destroy_devices(unsigned int nr)
|
||||||
{
|
{
|
||||||
sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
|
struct zram *zram;
|
||||||
&zram_disk_attr_group);
|
unsigned int i;
|
||||||
|
|
||||||
del_gendisk(zram->disk);
|
for (i = 0; i < nr; i++) {
|
||||||
put_disk(zram->disk);
|
zram = &zram_devices[i];
|
||||||
|
/*
|
||||||
|
* Remove sysfs first, so no one will perform a disksize
|
||||||
|
* store while we destroy the devices
|
||||||
|
*/
|
||||||
|
sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
|
||||||
|
&zram_disk_attr_group);
|
||||||
|
|
||||||
blk_cleanup_queue(zram->queue);
|
zram_reset_device(zram);
|
||||||
|
|
||||||
|
blk_cleanup_queue(zram->disk->queue);
|
||||||
|
del_gendisk(zram->disk);
|
||||||
|
put_disk(zram->disk);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(zram_devices);
|
||||||
|
unregister_blkdev(zram_major, "zram");
|
||||||
|
pr_info("Destroyed %u device(s)\n", nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init zram_init(void)
|
static int __init zram_init(void)
|
||||||
|
@ -1138,64 +1178,39 @@ static int __init zram_init(void)
|
||||||
if (num_devices > max_num_devices) {
|
if (num_devices > max_num_devices) {
|
||||||
pr_warn("Invalid value for num_devices: %u\n",
|
pr_warn("Invalid value for num_devices: %u\n",
|
||||||
num_devices);
|
num_devices);
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zram_major = register_blkdev(0, "zram");
|
zram_major = register_blkdev(0, "zram");
|
||||||
if (zram_major <= 0) {
|
if (zram_major <= 0) {
|
||||||
pr_warn("Unable to get major number\n");
|
pr_warn("Unable to get major number\n");
|
||||||
ret = -EBUSY;
|
return -EBUSY;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the device array and initialize each one */
|
/* Allocate the device array and initialize each one */
|
||||||
zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL);
|
zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL);
|
||||||
if (!zram_devices) {
|
if (!zram_devices) {
|
||||||
ret = -ENOMEM;
|
unregister_blkdev(zram_major, "zram");
|
||||||
goto unregister;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dev_id = 0; dev_id < num_devices; dev_id++) {
|
for (dev_id = 0; dev_id < num_devices; dev_id++) {
|
||||||
ret = create_device(&zram_devices[dev_id], dev_id);
|
ret = create_device(&zram_devices[dev_id], dev_id);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_devices;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("Created %u device(s) ...\n", num_devices);
|
pr_info("Created %u device(s)\n", num_devices);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_devices:
|
out_error:
|
||||||
while (dev_id)
|
destroy_devices(dev_id);
|
||||||
destroy_device(&zram_devices[--dev_id]);
|
|
||||||
kfree(zram_devices);
|
|
||||||
unregister:
|
|
||||||
unregister_blkdev(zram_major, "zram");
|
|
||||||
out:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit zram_exit(void)
|
static void __exit zram_exit(void)
|
||||||
{
|
{
|
||||||
int i;
|
destroy_devices(num_devices);
|
||||||
struct zram *zram;
|
|
||||||
|
|
||||||
for (i = 0; i < num_devices; i++) {
|
|
||||||
zram = &zram_devices[i];
|
|
||||||
|
|
||||||
destroy_device(zram);
|
|
||||||
/*
|
|
||||||
* Shouldn't access zram->disk after destroy_device
|
|
||||||
* because destroy_device already released zram->disk.
|
|
||||||
*/
|
|
||||||
zram_reset_device(zram, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
unregister_blkdev(zram_major, "zram");
|
|
||||||
|
|
||||||
kfree(zram_devices);
|
|
||||||
pr_debug("Cleanup done!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(zram_init);
|
module_init(zram_init);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue