reading kernel source
2014/02/24
$ git log --grep sync_supers
$ git describe --all --contains f0cd2dbb6cf387c11f87265462e370bb5469299e tags/v3.6-rc2~30^2~15チルダ以降の読み方がわからないのだけど, v3.6-rc2に含まれているのは確実..
NAME copy_to_user - Copy a block of data into user space. SYNOPSIS unsigned long copy_to_user(void __user * to, const void * from, unsigned long n); ARGUMENTS to Destination address, in user space. from Source address, in kernel space. n Number of bytes to copy. CONTEXT User context only. This function may sleep. DESCRIPTION Copy data from kernel space to user space. Returns number of bytes that could not be copied. On success, this will be zero.
.macro str1w ptr reg abort strusr \reg, \ptr, 4, abort=\abort .endmFILE: archinc/asm/assembler.h
.macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f usracc str, \reg, \ptr, \inc, \cond, \rept, \abort .endm .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER() .rept \rept 9999: .if \inc == 1 \instr\cond\()b\()\t \reg, [\ptr], #\inc .elseif \inc == 4 \instr\cond\()\t \reg, [\ptr], #\inc .else .error "Unsupported inc macro argument" .endif .pushsection __ex_table,"a" .align 3 .long 9999b, \abort .popsection .endr .endm usracc str, \reg, \ptr, \inc(=4), \cond(=none,al), \rept(=none,1), \abort(=pop) stral reg, [ptr], #inc .pushsection __ex_table,"a" .align 3 .long 9999b, \abort
. = ALIGN(4); __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { __start___ex_table = .; #ifdef CONFIG_MMU *(__ex_table) #endif __stop___ex_table = .;
/* Given an address, look for it in the exception tables. */ const struct exception_table_entry *search_exception_tables(unsigned long addr)さらにこれを使っているところを探すと、アーキ依存部のpage fault処理部分が見つかる。
int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fixup; fixup = search_exception_tables(instruction_pointer(regs)); if (fixup) { regs->ARM_pc = fixup->fixup; #ifdef CONFIG_THUMB2_KERNEL /* Clear the IT state to avoid nasty surprises in the fixup */ regs->ARM_cpsr &= ~PSR_IT_MASK; #endif } return fixup != NULL; }さらにさらに、これを使っているところを探すと、
/* * Oops. The kernel tried to access some page that wasn't present. */ static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs) { /* * Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) return;ここに来れば faultが発生しても、Oopsを吐かずに指定されたアドレスへ
static int __kprobes do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, /* * Don't allow RAM to be mapped - this causes problems with ARMv6+ */ if (WARN_ON(pfn_valid(pfn))) return NULL;
commit 576d2f2525612ecb5af029a76f21f22a3b82563d Author: Nicolas Pitre <nicolas.pitre@linaro.org> Date: Fri Sep 16 01:14:23 2011 -0400 ARM: add generic ioremap optimization by reusing static mappings Now that we have all the static mappings from iotable_init() located in the vmalloc area, it is trivial to optimize ioremap by reusing those static mappings when the requested physical area fits in one of them, and so in a generic way for all platforms. Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> Tested-by: Stephen Warren <swarren@nvidia.com> Tested-by: Kevin Hilman <khilman@ti.com> Tested-by: Jamie Iles <jamie@jamieiles.com>この手前で、vmlistの領域に引っかかっていれば、そのアドレスを返している(ioremapした空間だと思われ)。
commit 309caa9cc6ff39d261264ec4ff10e29489afc8f8 Author: Russell King <rmk+kernel@arm.linux.org.uk> Date: Mon Jun 21 21:03:18 2010 +0100 ARM: Prohibit ioremap() on kernel managed RAM ARMv6 and above have a restriction whereby aliasing virtual:physical mappings must not have differing memory type and sharability attributes. Strictly, this covers the memory type (strongly ordered, device, memory), cache attributes (uncached, write combine, write through, write back read alloc, write back write alloc) and the shared bit. However, using ioremap() and its variants on system RAM results in mappings which differ in these attributes from the main system RAM mapping. Other architectures which similar restrictions approch this problem in the same way - they do not permit ioremap on main system RAM. Make ARM behave in the same way, with a WARN_ON() such that users can be traced and an alternative approach found. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>FILE: arch/arm/mm/ioremap.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #define BLKSIZE 4096 #define BLKCOUNT (1024 * 1024 * 1024 / BLKSIZE) int main() { int i; int* p; fprintf(stderr, "We will allocate 1GB...\n"); sleep(30); for (i=0; i<BLKCOUNT; ++i) { p = (int*)malloc(BLKSIZE); *p = 0; } fprintf(stderr, "allocated BLKSIZE=%d, count=%d\n", BLKSIZE, i); sleep(30); fprintf(stderr, "exit...\n"); return 0; } /* sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches \ && free > free.before \ && cat /proc/meminfo > meminfo.before \ && cat /proc/slabinfo > slabinfo.before \ && cat /proc/buddyinfo > buddyinfo.before \ && cat /proc/$(pgrep a.out)/smaps > smaps.before \ && cat /proc/$(pgrep a.out)/maps > maps.before' ps -eFwl sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches \ && free > free.after \ && cat /proc/meminfo > meminfo.after \ && cat /proc/slabinfo > slabinfo.after \ && cat /proc/buddyinfo > buddyinfo.after \ && cat /proc/$(pgrep a.out)/smaps > smaps.after \ && cat /proc/$(pgrep a.out)/maps > maps.after' ps -eFwl */