diff options
| author | Srinivasarao P <spathi@codeaurora.org> | 2018-01-24 12:19:03 +0530 |
|---|---|---|
| committer | Srinivasarao P <spathi@codeaurora.org> | 2018-01-24 12:20:03 +0530 |
| commit | 1f4bd7c8ff243f52e0a23e3b9b981b59ec288d90 (patch) | |
| tree | 08bc508546470164cf08b1ecd4f7bc25d834cb42 /arch/x86/mm/kaiser.c | |
| parent | a5cabe9334b684f828dab1d28167d2b154536851 (diff) | |
| parent | f8518889ffe879b6266657e83b6cf6ace8111cdc (diff) | |
Merge android-4.4.111 (f851888) into msm-4.4
* refs/heads/tmp-f851888
Linux 4.4.111
Fix build error in vma.c
Map the vsyscall page with _PAGE_USER
proc: much faster /proc/vmstat
module: Issue warnings when tainting kernel
module: keep percpu symbols in module's symtab
genksyms: Handle string literals with spaces in reference files
x86/tlb: Drop the _GPL from the cpu_tlbstate export
parisc: Fix alignment of pa_tlb_lock in assembly on 32-bit SMP kernel
x86/microcode/AMD: Add support for fam17h microcode loading
Input: elantech - add new icbody type 15
ARC: uaccess: dont use "l" gcc inline asm constraint modifier
kernel/signal.c: remove the no longer needed SIGNAL_UNKILLABLE check in complete_signal()
kernel/signal.c: protect the SIGNAL_UNKILLABLE tasks from !sig_kernel_only() signals
kernel/signal.c: protect the traced SIGNAL_UNKILLABLE tasks from SIGKILL
kernel: make groups_sort calling a responsibility group_info allocators
fscache: Fix the default for fscache_maybe_release_page()
sunxi-rsb: Include OF based modalias in device uevent
crypto: pcrypt - fix freeing pcrypt instances
crypto: chacha20poly1305 - validate the digest size
crypto: n2 - cure use after free
kernel/acct.c: fix the acct->needcheck check in check_free_space()
x86/kasan: Write protect kasan zero shadow
clocksource: arch_timer: make virtual counter access configurable
arm64: issue isb when trapping CNTVCT_EL0 access
BACKPORT: arm64: Add CNTFRQ_EL0 trap handler
BACKPORT: arm64: Add CNTVCT_EL0 trap handler
ANDROID: sdcardfs: Fix missing break on default_normal
ANDROID: usb: f_fs: Prevent gadget unbind if it is already unbound
arm64: Kconfig: Reword UNMAP_KERNEL_AT_EL0 kconfig entry
arm64: use RET instruction for exiting the trampoline
FROMLIST: arm64: kaslr: Put kernel vectors address in separate data page
FROMLIST: arm64: mm: Introduce TTBR_ASID_MASK for getting at the ASID in the TTBR
FROMLIST: arm64: Kconfig: Add CONFIG_UNMAP_KERNEL_AT_EL0
FROMLIST: arm64: entry: Add fake CPU feature for unmapping the kernel at EL0
FROMLIST: arm64: tls: Avoid unconditional zeroing of tpidrro_el0 for native tasks
FROMLIST: arm64: erratum: Work around Falkor erratum #E1003 in trampoline code
FROMLIST: arm64: entry: Hook up entry trampoline to exception vectors
FROMLIST: arm64: entry: Explicitly pass exception level to kernel_ventry macro
FROMLIST: arm64: mm: Map entry trampoline into trampoline and kernel page tables
FROMLIST: arm64: entry: Add exception trampoline page for exceptions from EL0
FROMLIST: arm64: mm: Invalidate both kernel and user ASIDs when performing TLBI
FROMLIST: arm64: mm: Add arm64_kernel_unmapped_at_el0 helper
FROMLIST: arm64: mm: Allocate ASIDs in pairs
FROMLIST: arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN
FROMLIST: arm64: mm: Move ASID from TTBR0 to TTBR1
FROMLIST: arm64: mm: Temporarily disable ARM64_SW_TTBR0_PAN
FROMLIST: arm64: mm: Use non-global mappings for kernel space
UPSTREAM: arm64: factor out entry stack manipulation
UPSTREAM: arm64: tlbflush.h: add __tlbi() macro
Conflicts:
arch/arm64/include/asm/cpufeature.h
arch/arm64/kernel/asm-offsets.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/vmlinux.lds.S
drivers/clocksource/Kconfig
drivers/clocksource/arm_arch_timer.c
drivers/usb/gadget/function/f_fs.c
Change-Id: I41e84762e30c9a7b1e283850c3f780f3dbe86f44
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'arch/x86/mm/kaiser.c')
| -rw-r--r-- | arch/x86/mm/kaiser.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index b0b3a69f1c7f..6a7a77929a8c 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -20,6 +20,7 @@ #include <asm/pgalloc.h> #include <asm/desc.h> #include <asm/cmdline.h> +#include <asm/vsyscall.h> int kaiser_enabled __read_mostly = 1; EXPORT_SYMBOL(kaiser_enabled); /* for inlined TLB flush functions */ @@ -111,12 +112,13 @@ static inline unsigned long get_pa_from_mapping(unsigned long vaddr) * * Returns a pointer to a PTE on success, or NULL on failure. */ -static pte_t *kaiser_pagetable_walk(unsigned long address) +static pte_t *kaiser_pagetable_walk(unsigned long address, bool user) { pmd_t *pmd; pud_t *pud; pgd_t *pgd = native_get_shadow_pgd(pgd_offset_k(address)); gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); + unsigned long prot = _KERNPG_TABLE; if (pgd_none(*pgd)) { WARN_ONCE(1, "All shadow pgds should have been populated"); @@ -124,6 +126,17 @@ static pte_t *kaiser_pagetable_walk(unsigned long address) } BUILD_BUG_ON(pgd_large(*pgd) != 0); + if (user) { + /* + * The vsyscall page is the only page that will have + * _PAGE_USER set. Catch everything else. + */ + BUG_ON(address != VSYSCALL_ADDR); + + set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER)); + prot = _PAGE_TABLE; + } + pud = pud_offset(pgd, address); /* The shadow page tables do not use large mappings: */ if (pud_large(*pud)) { @@ -136,7 +149,7 @@ static pte_t *kaiser_pagetable_walk(unsigned long address) return NULL; spin_lock(&shadow_table_allocation_lock); if (pud_none(*pud)) { - set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page))); + set_pud(pud, __pud(prot | __pa(new_pmd_page))); __inc_zone_page_state(virt_to_page((void *) new_pmd_page), NR_KAISERTABLE); } else @@ -156,7 +169,7 @@ static pte_t *kaiser_pagetable_walk(unsigned long address) return NULL; spin_lock(&shadow_table_allocation_lock); if (pmd_none(*pmd)) { - set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(new_pte_page))); + set_pmd(pmd, __pmd(prot | __pa(new_pte_page))); __inc_zone_page_state(virt_to_page((void *) new_pte_page), NR_KAISERTABLE); } else @@ -192,7 +205,7 @@ static int kaiser_add_user_map(const void *__start_addr, unsigned long size, ret = -EIO; break; } - pte = kaiser_pagetable_walk(address); + pte = kaiser_pagetable_walk(address, flags & _PAGE_USER); if (!pte) { ret = -ENOMEM; break; @@ -319,6 +332,19 @@ void __init kaiser_init(void) kaiser_init_all_pgds(); + /* + * Note that this sets _PAGE_USER and it needs to happen when the + * pagetable hierarchy gets created, i.e., early. Otherwise + * kaiser_pagetable_walk() will encounter initialized PTEs in the + * hierarchy and not set the proper permissions, leading to the + * pagefaults with page-protection violations when trying to read the + * vsyscall page. For example. + */ + if (vsyscall_enabled()) + kaiser_add_user_map_early((void *)VSYSCALL_ADDR, + PAGE_SIZE, + __PAGE_KERNEL_VSYSCALL); + for_each_possible_cpu(cpu) { void *percpu_vaddr = __per_cpu_user_mapped_start + per_cpu_offset(cpu); |
