aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-05-05 15:19:36 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2014-05-05 16:19:01 -0400
commitf40c330091c7aa9956ab66f97a3abc8a68b67240 (patch)
treeb0c03dce9bf67eb15c98980a7323ca35122d10df
parent18d0a6fd227177fd243993179c90e454d0638b06 (diff)
x86, vdso: Move the vvar and hpet mappings next to the 64-bit vDSO
This makes the 64-bit and x32 vdsos use the same mechanism as the 32-bit vdso. Most of the churn is deleting all the old fixmap code. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Link: http://lkml.kernel.org/r/8af87023f57f6bb96ec8d17fce3f88018195b49b.1399317206.git.luto@amacapital.net Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/include/asm/fixmap.h11
-rw-r--r--arch/x86/include/asm/vvar.h20
-rw-r--r--arch/x86/include/uapi/asm/vsyscall.h7
-rw-r--r--arch/x86/kernel/cpu/common.c1
-rw-r--r--arch/x86/kernel/hpet.c3
-rw-r--r--arch/x86/kernel/vsyscall_64.c15
-rw-r--r--arch/x86/mm/fault.c5
-rw-r--r--arch/x86/mm/init_64.c10
-rw-r--r--arch/x86/vdso/vclock_gettime.c22
-rw-r--r--arch/x86/vdso/vdso-layout.lds.S2
-rw-r--r--arch/x86/xen/mmu.c8
11 files changed, 27 insertions, 77 deletions
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 43f482a0db37..b0910f97a3ea 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -24,7 +24,7 @@
24#include <linux/threads.h> 24#include <linux/threads.h>
25#include <asm/kmap_types.h> 25#include <asm/kmap_types.h>
26#else 26#else
27#include <asm/vsyscall.h> 27#include <uapi/asm/vsyscall.h>
28#endif 28#endif
29 29
30/* 30/*
@@ -41,7 +41,8 @@
41extern unsigned long __FIXADDR_TOP; 41extern unsigned long __FIXADDR_TOP;
42#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP) 42#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)
43#else 43#else
44#define FIXADDR_TOP (VSYSCALL_END-PAGE_SIZE) 44#define FIXADDR_TOP (round_up(VSYSCALL_ADDR + PAGE_SIZE, 1<<PMD_SHIFT) - \
45 PAGE_SIZE)
45#endif 46#endif
46 47
47 48
@@ -68,11 +69,7 @@ enum fixed_addresses {
68#ifdef CONFIG_X86_32 69#ifdef CONFIG_X86_32
69 FIX_HOLE, 70 FIX_HOLE,
70#else 71#else
71 VSYSCALL_LAST_PAGE, 72 VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
72 VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
73 + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
74 VVAR_PAGE,
75 VSYSCALL_HPET,
76#ifdef CONFIG_PARAVIRT_CLOCK 73#ifdef CONFIG_PARAVIRT_CLOCK
77 PVCLOCK_FIXMAP_BEGIN, 74 PVCLOCK_FIXMAP_BEGIN,
78 PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1, 75 PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index 081d909bc495..5d2b9ad2c6d2 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -29,31 +29,13 @@
29 29
30#else 30#else
31 31
32#ifdef BUILD_VDSO32 32extern char __vvar_page;
33 33
34#define DECLARE_VVAR(offset, type, name) \ 34#define DECLARE_VVAR(offset, type, name) \
35 extern type vvar_ ## name __attribute__((visibility("hidden"))); 35 extern type vvar_ ## name __attribute__((visibility("hidden")));
36 36
37#define VVAR(name) (vvar_ ## name) 37#define VVAR(name) (vvar_ ## name)
38 38
39#else
40
41extern char __vvar_page;
42
43/* Base address of vvars. This is not ABI. */
44#ifdef CONFIG_X86_64
45#define VVAR_ADDRESS (-10*1024*1024 - 4096)
46#else
47#define VVAR_ADDRESS (&__vvar_page)
48#endif
49
50#define DECLARE_VVAR(offset, type, name) \
51 static type const * const vvaraddr_ ## name = \
52 (void *)(VVAR_ADDRESS + (offset));
53
54#define VVAR(name) (*vvaraddr_ ## name)
55#endif
56
57#define DEFINE_VVAR(type, name) \ 39#define DEFINE_VVAR(type, name) \
58 type name \ 40 type name \
59 __attribute__((section(".vvar_" #name), aligned(16))) __visible 41 __attribute__((section(".vvar_" #name), aligned(16))) __visible
diff --git a/arch/x86/include/uapi/asm/vsyscall.h b/arch/x86/include/uapi/asm/vsyscall.h
index 85dc1b3825ab..b97dd6e263d2 100644
--- a/arch/x86/include/uapi/asm/vsyscall.h
+++ b/arch/x86/include/uapi/asm/vsyscall.h
@@ -7,11 +7,6 @@ enum vsyscall_num {
7 __NR_vgetcpu, 7 __NR_vgetcpu,
8}; 8};
9 9
10#define VSYSCALL_START (-10UL << 20) 10#define VSYSCALL_ADDR (-10UL << 20)
11#define VSYSCALL_SIZE 1024
12#define VSYSCALL_END (-2UL << 20)
13#define VSYSCALL_MAPPED_PAGES 1
14#define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
15
16 11
17#endif /* _UAPI_ASM_X86_VSYSCALL_H */ 12#endif /* _UAPI_ASM_X86_VSYSCALL_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7c65b4666c24..2cbbf88d8f2c 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -20,6 +20,7 @@
20#include <asm/processor.h> 20#include <asm/processor.h>
21#include <asm/debugreg.h> 21#include <asm/debugreg.h>
22#include <asm/sections.h> 22#include <asm/sections.h>
23#include <asm/vsyscall.h>
23#include <linux/topology.h> 24#include <linux/topology.h>
24#include <linux/cpumask.h> 25#include <linux/cpumask.h>
25#include <asm/pgtable.h> 26#include <asm/pgtable.h>
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 8d80ae011603..bbc15a0362d2 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -74,9 +74,6 @@ static inline void hpet_writel(unsigned int d, unsigned int a)
74static inline void hpet_set_mapping(void) 74static inline void hpet_set_mapping(void)
75{ 75{
76 hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); 76 hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
77#ifdef CONFIG_X86_64
78 __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VVAR_NOCACHE);
79#endif
80} 77}
81 78
82static inline void hpet_clear_mapping(void) 79static inline void hpet_clear_mapping(void)
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 8b3b3eb3cead..ea5b5709aa76 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -91,7 +91,7 @@ static int addr_to_vsyscall_nr(unsigned long addr)
91{ 91{
92 int nr; 92 int nr;
93 93
94 if ((addr & ~0xC00UL) != VSYSCALL_START) 94 if ((addr & ~0xC00UL) != VSYSCALL_ADDR)
95 return -EINVAL; 95 return -EINVAL;
96 96
97 nr = (addr & 0xC00UL) >> 10; 97 nr = (addr & 0xC00UL) >> 10;
@@ -330,24 +330,17 @@ void __init map_vsyscall(void)
330{ 330{
331 extern char __vsyscall_page; 331 extern char __vsyscall_page;
332 unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); 332 unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
333 unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page);
334 333
335 __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall, 334 __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
336 vsyscall_mode == NATIVE 335 vsyscall_mode == NATIVE
337 ? PAGE_KERNEL_VSYSCALL 336 ? PAGE_KERNEL_VSYSCALL
338 : PAGE_KERNEL_VVAR); 337 : PAGE_KERNEL_VVAR);
339 BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_FIRST_PAGE) != 338 BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
340 (unsigned long)VSYSCALL_START); 339 (unsigned long)VSYSCALL_ADDR);
341
342 __set_fixmap(VVAR_PAGE, physaddr_vvar_page, PAGE_KERNEL_VVAR);
343 BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) !=
344 (unsigned long)VVAR_ADDRESS);
345} 340}
346 341
347static int __init vsyscall_init(void) 342static int __init vsyscall_init(void)
348{ 343{
349 BUG_ON(VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE));
350
351 cpu_notifier_register_begin(); 344 cpu_notifier_register_begin();
352 345
353 on_each_cpu(cpu_vsyscall_init, NULL, 1); 346 on_each_cpu(cpu_vsyscall_init, NULL, 1);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 8e5722992677..858b47b5221b 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -18,7 +18,8 @@
18#include <asm/traps.h> /* dotraplinkage, ... */ 18#include <asm/traps.h> /* dotraplinkage, ... */
19#include <asm/pgalloc.h> /* pgd_*(), ... */ 19#include <asm/pgalloc.h> /* pgd_*(), ... */
20#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ 20#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
21#include <asm/fixmap.h> /* VSYSCALL_START */ 21#include <asm/fixmap.h> /* VSYSCALL_ADDR */
22#include <asm/vsyscall.h> /* emulate_vsyscall */
22 23
23#define CREATE_TRACE_POINTS 24#define CREATE_TRACE_POINTS
24#include <asm/trace/exceptions.h> 25#include <asm/trace/exceptions.h>
@@ -771,7 +772,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
771 * emulation. 772 * emulation.
772 */ 773 */
773 if (unlikely((error_code & PF_INSTR) && 774 if (unlikely((error_code & PF_INSTR) &&
774 ((address & ~0xfff) == VSYSCALL_START))) { 775 ((address & ~0xfff) == VSYSCALL_ADDR))) {
775 if (emulate_vsyscall(regs, address)) 776 if (emulate_vsyscall(regs, address))
776 return; 777 return;
777 } 778 }
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 563849600d3e..6f881842116c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1055,8 +1055,8 @@ void __init mem_init(void)
1055 after_bootmem = 1; 1055 after_bootmem = 1;
1056 1056
1057 /* Register memory areas for /proc/kcore */ 1057 /* Register memory areas for /proc/kcore */
1058 kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 1058 kclist_add(&kcore_vsyscall, (void *)VSYSCALL_ADDR,
1059 VSYSCALL_END - VSYSCALL_START, KCORE_OTHER); 1059 PAGE_SIZE, KCORE_OTHER);
1060 1060
1061 mem_init_print_info(NULL); 1061 mem_init_print_info(NULL);
1062} 1062}
@@ -1186,8 +1186,8 @@ int kern_addr_valid(unsigned long addr)
1186 * not need special handling anymore: 1186 * not need special handling anymore:
1187 */ 1187 */
1188static struct vm_area_struct gate_vma = { 1188static struct vm_area_struct gate_vma = {
1189 .vm_start = VSYSCALL_START, 1189 .vm_start = VSYSCALL_ADDR,
1190 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE), 1190 .vm_end = VSYSCALL_ADDR + PAGE_SIZE,
1191 .vm_page_prot = PAGE_READONLY_EXEC, 1191 .vm_page_prot = PAGE_READONLY_EXEC,
1192 .vm_flags = VM_READ | VM_EXEC 1192 .vm_flags = VM_READ | VM_EXEC
1193}; 1193};
@@ -1218,7 +1218,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)
1218 */ 1218 */
1219int in_gate_area_no_mm(unsigned long addr) 1219int in_gate_area_no_mm(unsigned long addr)
1220{ 1220{
1221 return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); 1221 return (addr & PAGE_MASK) == VSYSCALL_ADDR;
1222} 1222}
1223 1223
1224const char *arch_vma_name(struct vm_area_struct *vma) 1224const char *arch_vma_name(struct vm_area_struct *vma)
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
index 091554c20bc9..b2e4f493e5b0 100644
--- a/arch/x86/vdso/vclock_gettime.c
+++ b/arch/x86/vdso/vclock_gettime.c
@@ -30,9 +30,12 @@ extern int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz);
30extern time_t __vdso_time(time_t *t); 30extern time_t __vdso_time(time_t *t);
31 31
32#ifdef CONFIG_HPET_TIMER 32#ifdef CONFIG_HPET_TIMER
33static inline u32 read_hpet_counter(const volatile void *addr) 33extern u8 hpet_page
34 __attribute__((visibility("hidden")));
35
36static notrace cycle_t vread_hpet(void)
34{ 37{
35 return *(const volatile u32 *) (addr + HPET_COUNTER); 38 return *(const volatile u32 *)(&hpet_page + HPET_COUNTER);
36} 39}
37#endif 40#endif
38 41
@@ -43,11 +46,6 @@ static inline u32 read_hpet_counter(const volatile void *addr)
43#include <asm/fixmap.h> 46#include <asm/fixmap.h>
44#include <asm/pvclock.h> 47#include <asm/pvclock.h>
45 48
46static notrace cycle_t vread_hpet(void)
47{
48 return read_hpet_counter((const void *)fix_to_virt(VSYSCALL_HPET));
49}
50
51notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) 49notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
52{ 50{
53 long ret; 51 long ret;
@@ -137,16 +135,6 @@ static notrace cycle_t vread_pvclock(int *mode)
137 135
138#else 136#else
139 137
140extern u8 hpet_page
141 __attribute__((visibility("hidden")));
142
143#ifdef CONFIG_HPET_TIMER
144static notrace cycle_t vread_hpet(void)
145{
146 return read_hpet_counter((const void *)(&hpet_page));
147}
148#endif
149
150notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) 138notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
151{ 139{
152 long ret; 140 long ret;
diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S
index e177c08bb4bc..2ec72f651ebf 100644
--- a/arch/x86/vdso/vdso-layout.lds.S
+++ b/arch/x86/vdso/vdso-layout.lds.S
@@ -47,7 +47,6 @@ SECTIONS
47 47
48 .text : { *(.text*) } :text =0x90909090, 48 .text : { *(.text*) } :text =0x90909090,
49 49
50#ifdef BUILD_VDSO32
51 /* 50 /*
52 * The remainder of the vDSO consists of special pages that are 51 * The remainder of the vDSO consists of special pages that are
53 * shared between the kernel and userspace. It needs to be at the 52 * shared between the kernel and userspace. It needs to be at the
@@ -69,7 +68,6 @@ SECTIONS
69 68
70 hpet_page = .; 69 hpet_page = .;
71 . = . + PAGE_SIZE; 70 . = . + PAGE_SIZE;
72#endif
73 71
74 . = ALIGN(PAGE_SIZE); 72 . = ALIGN(PAGE_SIZE);
75 end_mapping = .; 73 end_mapping = .;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 86e02eabb640..3060568248d3 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1494,7 +1494,7 @@ static int xen_pgd_alloc(struct mm_struct *mm)
1494 page->private = (unsigned long)user_pgd; 1494 page->private = (unsigned long)user_pgd;
1495 1495
1496 if (user_pgd != NULL) { 1496 if (user_pgd != NULL) {
1497 user_pgd[pgd_index(VSYSCALL_START)] = 1497 user_pgd[pgd_index(VSYSCALL_ADDR)] =
1498 __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE); 1498 __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
1499 ret = 0; 1499 ret = 0;
1500 } 1500 }
@@ -2062,8 +2062,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2062 case FIX_KMAP_BEGIN ... FIX_KMAP_END: 2062 case FIX_KMAP_BEGIN ... FIX_KMAP_END:
2063# endif 2063# endif
2064#else 2064#else
2065 case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: 2065 case VSYSCALL_PAGE:
2066 case VVAR_PAGE:
2067#endif 2066#endif
2068 case FIX_TEXT_POKE0: 2067 case FIX_TEXT_POKE0:
2069 case FIX_TEXT_POKE1: 2068 case FIX_TEXT_POKE1:
@@ -2104,8 +2103,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2104#ifdef CONFIG_X86_64 2103#ifdef CONFIG_X86_64
2105 /* Replicate changes to map the vsyscall page into the user 2104 /* Replicate changes to map the vsyscall page into the user
2106 pagetable vsyscall mapping. */ 2105 pagetable vsyscall mapping. */
2107 if ((idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) || 2106 if (idx == VSYSCALL_PAGE) {
2108 idx == VVAR_PAGE) {
2109 unsigned long vaddr = __fix_to_virt(idx); 2107 unsigned long vaddr = __fix_to_virt(idx);
2110 set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte); 2108 set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte);
2111 } 2109 }