mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17
@ 2014-06-17  2:23 Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 1/8] x86_64,vsyscall: Fix warn_bad_vsyscall log output Andy Lutomirski
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

This is mostly cleanups.  Patch 1 fixes a minor bug; it might make sense
to backport it.

Patch 3 removes the vsyscall mapping when vsyscall=none.

Patches 4 and 5 remove everything except gtod from the vvar page; the
other vvars weren't really necessary.

Patch 2, 6, 7, and 8 are pure cleanups.

This is based on tip/x86/vdso.

Andy Lutomirski (8):
  x86_64,vsyscall: Fix warn_bad_vsyscall log output
  x86_64,vsyscall: Move all of the gate_area code to vsyscall_64.c
  x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none
  x86_64,vdso: Remove jiffies from the vvar page
  x86,vdso: Replace vgetcpu_mode with static_cpu_has
  x86_64: Move getcpu code from vsyscall_64.c to vdso/vma.c
  x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
  x86_64,vdso: Clean up vgetcpu init and merge the vdso initcalls

 arch/x86/include/asm/vgtod.h    |  21 ++++++
 arch/x86/include/asm/vsyscall.h |  29 --------
 arch/x86/include/asm/vvar.h     |   2 -
 arch/x86/kernel/cpu/common.c    |  10 ---
 arch/x86/kernel/time.c          |   2 +-
 arch/x86/kernel/vsyscall_64.c   | 155 +++++++++++++++++-----------------------
 arch/x86/mm/init_64.c           |  49 -------------
 arch/x86/vdso/vclock_gettime.c  |   3 +
 arch/x86/vdso/vgetcpu.c         |   5 +-
 arch/x86/vdso/vma.c             |  81 ++++++++++++++++-----
 10 files changed, 158 insertions(+), 199 deletions(-)

-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/8] x86_64,vsyscall: Fix warn_bad_vsyscall log output
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 2/8] x86_64,vsyscall: Move all of the gate_area code to vsyscall_64.c Andy Lutomirski
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski, stable

This commit in Linux 3.6:

    commit c767a54ba0657e52e6edaa97cbe0b0a8bf1c1655
    Author: Joe Perches <joe@perches.com>
    Date:   Mon May 21 19:50:07 2012 -0700

        x86/debug: Add KERN_<LEVEL> to bare printks, convert printks to pr_<level>

caused warn_bad_vsyscall to output garbage in the middle of the
line.  Revert the bad part of it.

The printk in question isn't actually bare; the level is "%s".

The bug this fixes is purely cosmetic; backports are optional.

Cc: stable@vger.kernel.org
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/kernel/vsyscall_64.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index ea5b570..e1e1e80 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -81,10 +81,10 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
 	if (!show_unhandled_signals)
 		return;
 
-	pr_notice_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n",
-			      level, current->comm, task_pid_nr(current),
-			      message, regs->ip, regs->cs,
-			      regs->sp, regs->ax, regs->si, regs->di);
+	printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n",
+			   level, current->comm, task_pid_nr(current),
+			   message, regs->ip, regs->cs,
+			   regs->sp, regs->ax, regs->si, regs->di);
 }
 
 static int addr_to_vsyscall_nr(unsigned long addr)
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/8] x86_64,vsyscall: Move all of the gate_area code to vsyscall_64.c
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 1/8] x86_64,vsyscall: Fix warn_bad_vsyscall log output Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 3/8] x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none Andy Lutomirski
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

This code exists for the sole purpose of making the vsyscall page
look sort of like real userspace memory.  Move it so that it lives
with the rest of the vsyscall code.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/kernel/vsyscall_64.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 arch/x86/mm/init_64.c         | 49 -------------------------------------------
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index e1e1e80..420c468 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -284,6 +284,55 @@ sigsegv:
 }
 
 /*
+ * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
+ * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
+ * not need special handling anymore:
+ */
+static const char *gate_vma_name(struct vm_area_struct *vma)
+{
+	return "[vsyscall]";
+}
+static struct vm_operations_struct gate_vma_ops = {
+	.name = gate_vma_name,
+};
+static struct vm_area_struct gate_vma = {
+	.vm_start	= VSYSCALL_ADDR,
+	.vm_end		= VSYSCALL_ADDR + PAGE_SIZE,
+	.vm_page_prot	= PAGE_READONLY_EXEC,
+	.vm_flags	= VM_READ | VM_EXEC,
+	.vm_ops		= &gate_vma_ops,
+};
+
+struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+#ifdef CONFIG_IA32_EMULATION
+	if (!mm || mm->context.ia32_compat)
+		return NULL;
+#endif
+	return &gate_vma;
+}
+
+int in_gate_area(struct mm_struct *mm, unsigned long addr)
+{
+	struct vm_area_struct *vma = get_gate_vma(mm);
+
+	if (!vma)
+		return 0;
+
+	return (addr >= vma->vm_start) && (addr < vma->vm_end);
+}
+
+/*
+ * Use this when you have no reliable mm, typically from interrupt
+ * context. It is less reliable than using a task's mm and may give
+ * false positives.
+ */
+int in_gate_area_no_mm(unsigned long addr)
+{
+	return (addr & PAGE_MASK) == VSYSCALL_ADDR;
+}
+
+/*
  * Assume __initcall executes before all user space. Hopefully kmod
  * doesn't violate that. We'll find out if it does.
  */
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index df1a992..417ea05 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1180,55 +1180,6 @@ int kern_addr_valid(unsigned long addr)
 	return pfn_valid(pte_pfn(*pte));
 }
 
-/*
- * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
- * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
- * not need special handling anymore:
- */
-static const char *gate_vma_name(struct vm_area_struct *vma)
-{
-	return "[vsyscall]";
-}
-static struct vm_operations_struct gate_vma_ops = {
-	.name = gate_vma_name,
-};
-static struct vm_area_struct gate_vma = {
-	.vm_start	= VSYSCALL_ADDR,
-	.vm_end		= VSYSCALL_ADDR + PAGE_SIZE,
-	.vm_page_prot	= PAGE_READONLY_EXEC,
-	.vm_flags	= VM_READ | VM_EXEC,
-	.vm_ops		= &gate_vma_ops,
-};
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
-#ifdef CONFIG_IA32_EMULATION
-	if (!mm || mm->context.ia32_compat)
-		return NULL;
-#endif
-	return &gate_vma;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
-	struct vm_area_struct *vma = get_gate_vma(mm);
-
-	if (!vma)
-		return 0;
-
-	return (addr >= vma->vm_start) && (addr < vma->vm_end);
-}
-
-/*
- * Use this when you have no reliable mm, typically from interrupt
- * context. It is less reliable than using a task's mm and may give
- * false positives.
- */
-int in_gate_area_no_mm(unsigned long addr)
-{
-	return (addr & PAGE_MASK) == VSYSCALL_ADDR;
-}
-
 static unsigned long probe_memory_block_size(void)
 {
 	/* start from 2g */
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/8] x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 1/8] x86_64,vsyscall: Fix warn_bad_vsyscall log output Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 2/8] x86_64,vsyscall: Move all of the gate_area code to vsyscall_64.c Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 4/8] x86_64,vdso: Remove jiffies from the vvar page Andy Lutomirski
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

I see no point in having an unusable read-only page sitting at
0xffffffffff600000 when vsyscall=none.  Instead, skip mapping it and
remove it from /proc/PID/maps.

I kept the ratelimited warning when programs try to use a vsyscall
in this mode, since it may help admins avoid confusion.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/kernel/vsyscall_64.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 420c468..6463f9e 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -309,6 +309,8 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 	if (!mm || mm->context.ia32_compat)
 		return NULL;
 #endif
+	if (vsyscall_mode == NONE)
+		return NULL;
 	return &gate_vma;
 }
 
@@ -329,7 +331,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)
  */
 int in_gate_area_no_mm(unsigned long addr)
 {
-	return (addr & PAGE_MASK) == VSYSCALL_ADDR;
+	return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR;
 }
 
 /*
@@ -380,10 +382,12 @@ void __init map_vsyscall(void)
 	extern char __vsyscall_page;
 	unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
 
-	__set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
-		     vsyscall_mode == NATIVE
-		     ? PAGE_KERNEL_VSYSCALL
-		     : PAGE_KERNEL_VVAR);
+	if (vsyscall_mode != NONE)
+		__set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
+			     vsyscall_mode == NATIVE
+			     ? PAGE_KERNEL_VSYSCALL
+			     : PAGE_KERNEL_VVAR);
+
 	BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
 		     (unsigned long)VSYSCALL_ADDR);
 }
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/8] x86_64,vdso: Remove jiffies from the vvar page
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
                   ` (2 preceding siblings ...)
  2014-06-17  2:23 ` [PATCH 3/8] x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 5/8] x86,vdso: Replace vgetcpu_mode with static_cpu_has Andy Lutomirski
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

I think that the jiffies vvar was once used for the vgetcpu cache.
That code is long gone, so let's just make jiffies be a normal
variable.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/include/asm/vvar.h | 1 -
 arch/x86/kernel/time.c      | 2 +-
 arch/x86/vdso/vgetcpu.c     | 1 -
 3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index 5d2b9ad..5f6d407 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -44,7 +44,6 @@ extern char __vvar_page;
 
 /* DECLARE_VVAR(offset, type, name) */
 
-DECLARE_VVAR(0, volatile unsigned long, jiffies)
 DECLARE_VVAR(16, int, vgetcpu_mode)
 DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
 
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index bf7ef5c..822773b 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -23,7 +23,7 @@
 #include <asm/time.h>
 
 #ifdef CONFIG_X86_64
-__visible DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES;
+__visible volatile unsigned long jiffies __cacheline_aligned = INITIAL_JIFFIES;
 #endif
 
 unsigned long profile_pc(struct pt_regs *regs)
diff --git a/arch/x86/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c
index 2f94b03..add1d98 100644
--- a/arch/x86/vdso/vgetcpu.c
+++ b/arch/x86/vdso/vgetcpu.c
@@ -7,7 +7,6 @@
 
 #include <linux/kernel.h>
 #include <linux/getcpu.h>
-#include <linux/jiffies.h>
 #include <linux/time.h>
 #include <asm/vsyscall.h>
 #include <asm/vgtod.h>
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/8] x86,vdso: Replace vgetcpu_mode with static_cpu_has
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
                   ` (3 preceding siblings ...)
  2014-06-17  2:23 ` [PATCH 4/8] x86_64,vdso: Remove jiffies from the vvar page Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 6/8] x86_64: Move getcpu code from vsyscall_64.c to vdso/vma.c Andy Lutomirski
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

The vdso has supported alternatives for a while; use them instead of
a vvar to select the vgetcpu mode.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/include/asm/vgtod.h    | 21 +++++++++++++++++++++
 arch/x86/include/asm/vsyscall.h | 29 -----------------------------
 arch/x86/include/asm/vvar.h     |  1 -
 arch/x86/kernel/cpu/common.c    | 10 ----------
 arch/x86/kernel/vsyscall_64.c   |  2 --
 arch/x86/vdso/vclock_gettime.c  |  3 +++
 arch/x86/vdso/vgetcpu.c         |  4 +++-
 arch/x86/vdso/vma.c             |  1 +
 8 files changed, 28 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index 3c3366c..44e0037 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -70,4 +70,25 @@ static inline void gtod_write_end(struct vsyscall_gtod_data *s)
 	++s->seq;
 }
 
+#ifdef CONFIG_X86_64
+
+#define VGETCPU_CPU_MASK 0xfff
+
+static inline unsigned int __getcpu(void)
+{
+	unsigned int p;
+
+	if (static_cpu_has(X86_FEATURE_RDTSCP)) {
+		/* Load per CPU data from RDTSCP */
+		native_read_tscp(&p);
+	} else {
+		/* Load per CPU data from GDT */
+		asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
+	}
+
+	return p;
+}
+
+#endif /* CONFIG_X86_64 */
+
 #endif /* _ASM_X86_VGTOD_H */
diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
index 2a46ca7..34f7d88 100644
--- a/arch/x86/include/asm/vsyscall.h
+++ b/arch/x86/include/asm/vsyscall.h
@@ -4,15 +4,6 @@
 #include <linux/seqlock.h>
 #include <uapi/asm/vsyscall.h>
 
-#define VGETCPU_RDTSCP	1
-#define VGETCPU_LSL	2
-
-/* kernel space (writeable) */
-extern int vgetcpu_mode;
-extern struct timezone sys_tz;
-
-#include <asm/vvar.h>
-
 extern void map_vsyscall(void);
 
 /*
@@ -21,24 +12,4 @@ extern void map_vsyscall(void);
  */
 extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
 
-#ifdef CONFIG_X86_64
-
-#define VGETCPU_CPU_MASK 0xfff
-
-static inline unsigned int __getcpu(void)
-{
-	unsigned int p;
-
-	if (VVAR(vgetcpu_mode) == VGETCPU_RDTSCP) {
-		/* Load per CPU data from RDTSCP */
-		native_read_tscp(&p);
-	} else {
-		/* Load per CPU data from GDT */
-		asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
-	}
-
-	return p;
-}
-#endif /* CONFIG_X86_64 */
-
 #endif /* _ASM_X86_VSYSCALL_H */
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index 5f6d407..3f32dfc 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -44,7 +44,6 @@ extern char __vvar_page;
 
 /* DECLARE_VVAR(offset, type, name) */
 
-DECLARE_VVAR(16, int, vgetcpu_mode)
 DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
 
 #undef DECLARE_VVAR
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2cbbf88..cc41df0 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -947,14 +947,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 }
 
 #ifdef CONFIG_X86_64
-static void vgetcpu_set_mode(void)
-{
-	if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
-		vgetcpu_mode = VGETCPU_RDTSCP;
-	else
-		vgetcpu_mode = VGETCPU_LSL;
-}
-
 /* May not be __init: called during resume */
 static void syscall32_cpu_init(void)
 {
@@ -995,8 +987,6 @@ void __init identify_boot_cpu(void)
 #ifdef CONFIG_X86_32
 	sysenter_setup();
 	enable_sep_cpu();
-#else
-	vgetcpu_set_mode();
 #endif
 	cpu_detect_tlb(&boot_cpu_data);
 }
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 6463f9e..dd1b322 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -52,8 +52,6 @@
 #define CREATE_TRACE_POINTS
 #include "vsyscall_trace.h"
 
-DEFINE_VVAR(int, vgetcpu_mode);
-
 static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
 
 static int __init vsyscall_setup(char *str)
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
index b2e4f49..87df0af 100644
--- a/arch/x86/vdso/vclock_gettime.c
+++ b/arch/x86/vdso/vclock_gettime.c
@@ -14,6 +14,9 @@
 /* Disable profiling for userspace code: */
 #define DISABLE_BRANCH_PROFILING
 
+/* Disable static_cpu_has debugging; it doesn't work in the vDSO */
+#undef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+
 #include <uapi/linux/time.h>
 #include <asm/vgtod.h>
 #include <asm/hpet.h>
diff --git a/arch/x86/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c
index add1d98..fd8470c 100644
--- a/arch/x86/vdso/vgetcpu.c
+++ b/arch/x86/vdso/vgetcpu.c
@@ -5,10 +5,12 @@
  * Fast user context implementation of getcpu()
  */
 
+/* Disable static_cpu_has debugging; it doesn't work in the vDSO */
+#undef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+
 #include <linux/kernel.h>
 #include <linux/getcpu.h>
 #include <linux/time.h>
-#include <asm/vsyscall.h>
 #include <asm/vgtod.h>
 
 notrace long
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index e1513c4..67a8b6c 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -16,6 +16,7 @@
 #include <asm/vdso.h>
 #include <asm/page.h>
 #include <asm/hpet.h>
+#include <asm/vvar.h>
 
 #if defined(CONFIG_X86_64)
 unsigned int __read_mostly vdso64_enabled = 1;
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/8] x86_64: Move getcpu code from vsyscall_64.c to vdso/vma.c
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
                   ` (4 preceding siblings ...)
  2014-06-17  2:23 ` [PATCH 5/8] x86,vdso: Replace vgetcpu_mode with static_cpu_has Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 7/8] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 8/8] x86_64,vdso: Clean up vgetcpu init and merge the vdso initcalls Andy Lutomirski
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

This is pure cut-and-paste.  At this point, vsyscall_64.c contains
only code needed for vsyscall emulation, but some of the comments
and function names are still confused.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/kernel/vsyscall_64.c | 57 ----------------------------------------
 arch/x86/vdso/vma.c           | 61 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 57 deletions(-)

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index dd1b322..5029be3 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -332,49 +332,6 @@ int in_gate_area_no_mm(unsigned long addr)
 	return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR;
 }
 
-/*
- * Assume __initcall executes before all user space. Hopefully kmod
- * doesn't violate that. We'll find out if it does.
- */
-static void vsyscall_set_cpu(int cpu)
-{
-	unsigned long d;
-	unsigned long node = 0;
-#ifdef CONFIG_NUMA
-	node = cpu_to_node(cpu);
-#endif
-	if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
-		write_rdtscp_aux((node << 12) | cpu);
-
-	/*
-	 * Store cpu number in limit so that it can be loaded quickly
-	 * in user space in vgetcpu. (12 bits for the CPU and 8 bits for the node)
-	 */
-	d = 0x0f40000000000ULL;
-	d |= cpu;
-	d |= (node & 0xf) << 12;
-	d |= (node >> 4) << 48;
-
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
-}
-
-static void cpu_vsyscall_init(void *arg)
-{
-	/* preemption should be already off */
-	vsyscall_set_cpu(raw_smp_processor_id());
-}
-
-static int
-cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
-{
-	long cpu = (long)arg;
-
-	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
-		smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 1);
-
-	return NOTIFY_DONE;
-}
-
 void __init map_vsyscall(void)
 {
 	extern char __vsyscall_page;
@@ -389,17 +346,3 @@ void __init map_vsyscall(void)
 	BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
 		     (unsigned long)VSYSCALL_ADDR);
 }
-
-static int __init vsyscall_init(void)
-{
-	cpu_notifier_register_begin();
-
-	on_each_cpu(cpu_vsyscall_init, NULL, 1);
-	/* notifier priority > KVM */
-	__hotcpu_notifier(cpu_vsyscall_notifier, 30);
-
-	cpu_notifier_register_done();
-
-	return 0;
-}
-__initcall(vsyscall_init);
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 67a8b6c..8973b4e 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/random.h>
 #include <linux/elf.h>
+#include <linux/cpu.h>
 #include <asm/vsyscall.h>
 #include <asm/vgtod.h>
 #include <asm/proto.h>
@@ -17,6 +18,7 @@
 #include <asm/page.h>
 #include <asm/hpet.h>
 #include <asm/vvar.h>
+#include <asm/desc.h>
 
 #if defined(CONFIG_X86_64)
 unsigned int __read_mostly vdso64_enabled = 1;
@@ -233,3 +235,62 @@ static __init int vdso_setup(char *s)
 }
 __setup("vdso=", vdso_setup);
 #endif
+
+#ifdef CONFIG_X86_64
+/*
+ * Assume __initcall executes before all user space. Hopefully kmod
+ * doesn't violate that. We'll find out if it does.
+ */
+static void vsyscall_set_cpu(int cpu)
+{
+	unsigned long d;
+	unsigned long node = 0;
+#ifdef CONFIG_NUMA
+	node = cpu_to_node(cpu);
+#endif
+	if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
+		write_rdtscp_aux((node << 12) | cpu);
+
+	/*
+	 * Store cpu number in limit so that it can be loaded quickly
+	 * in user space in vgetcpu. (12 bits for the CPU and 8 bits for the node)
+	 */
+	d = 0x0f40000000000ULL;
+	d |= cpu;
+	d |= (node & 0xf) << 12;
+	d |= (node >> 4) << 48;
+
+	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+}
+
+static void cpu_vsyscall_init(void *arg)
+{
+	/* preemption should be already off */
+	vsyscall_set_cpu(raw_smp_processor_id());
+}
+
+static int
+cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
+{
+	long cpu = (long)arg;
+
+	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
+		smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 1);
+
+	return NOTIFY_DONE;
+}
+
+static int __init vsyscall_init(void)
+{
+	cpu_notifier_register_begin();
+
+	on_each_cpu(cpu_vsyscall_init, NULL, 1);
+	/* notifier priority > KVM */
+	__hotcpu_notifier(cpu_vsyscall_notifier, 30);
+
+	cpu_notifier_register_done();
+
+	return 0;
+}
+__initcall(vsyscall_init);
+#endif
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/8] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
                   ` (5 preceding siblings ...)
  2014-06-17  2:23 ` [PATCH 6/8] x86_64: Move getcpu code from vsyscall_64.c to vdso/vma.c Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  2014-06-17  2:23 ` [PATCH 8/8] x86_64,vdso: Clean up vgetcpu init and merge the vdso initcalls Andy Lutomirski
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

vsyscall_64.c is just vsyscall emulation.  Tidy it up accordingly.

If my comment editing offends anyone, let me know and I can fix it.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/kernel/vsyscall_64.c | 51 +++++++++++++++----------------------------
 1 file changed, 18 insertions(+), 33 deletions(-)

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 5029be3..1ea34e7 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -1,52 +1,37 @@
 /*
- *  Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
- *  Copyright 2003 Andi Kleen, SuSE Labs.
+ * Mostly copyright (c) 2012-2014 Andy Lutomirski <luto@amacapital.net>
  *
- *  [ NOTE: this mechanism is now deprecated in favor of the vDSO. ]
+ * This file implements vsyscall emulation.  vsyscalls are a legacy ABI:
+ * userspace can request certain kernel services by calling fixed
+ * addresses.  This concept is problematic:
  *
- *  Thanks to hpa@transmeta.com for some useful hint.
- *  Special thanks to Ingo Molnar for his early experience with
- *  a different vsyscall implementation for Linux/IA32 and for the name.
+ * - It interferes with ASLR.
+ * - It's awkward to write code that lives in kernel addresses but is
+ *   callable by userspace at fixed addresses.
+ * - The whole concept is impossible for 32-bit compat userspace.
+ * - UML cannot easily virtualize a vsyscall.
  *
- *  vsyscall 1 is located at -10Mbyte, vsyscall 2 is located
- *  at virtual address -10Mbyte+1024bytes etc... There are at max 4
- *  vsyscalls. One vsyscall can reserve more than 1 slot to avoid
- *  jumping out of line if necessary. We cannot add more with this
- *  mechanism because older kernels won't return -ENOSYS.
+ * As of mid-2014, I believe that there is no new userspace code that
+ * will use a vsyscall if the vDSO is present.  I hope that there will
+ * soon be no new userspace code that will ever use a vsyscall.
  *
- *  Note: the concept clashes with user mode linux.  UML users should
- *  use the vDSO.
+ * The code in this file emulates vsyscalls when notified of a page
+ * fault to a vsyscall address.
+ *
+ * The original version of this code is:
+ * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
+ * Copyright 2003 Andi Kleen, SuSE Labs.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/time.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
-#include <linux/seqlock.h>
-#include <linux/jiffies.h>
-#include <linux/sysctl.h>
-#include <linux/topology.h>
-#include <linux/timekeeper_internal.h>
-#include <linux/getcpu.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/notifier.h>
 #include <linux/syscalls.h>
 #include <linux/ratelimit.h>
 
 #include <asm/vsyscall.h>
-#include <asm/pgtable.h>
-#include <asm/compat.h>
-#include <asm/page.h>
 #include <asm/unistd.h>
 #include <asm/fixmap.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/segment.h>
-#include <asm/desc.h>
-#include <asm/topology.h>
 #include <asm/traps.h>
 
 #define CREATE_TRACE_POINTS
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/8] x86_64,vdso: Clean up vgetcpu init and merge the vdso initcalls
  2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
                   ` (6 preceding siblings ...)
  2014-06-17  2:23 ` [PATCH 7/8] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code Andy Lutomirski
@ 2014-06-17  2:23 ` Andy Lutomirski
  7 siblings, 0 replies; 9+ messages in thread
From: Andy Lutomirski @ 2014-06-17  2:23 UTC (permalink / raw)
  To: x86, linux-kernel; +Cc: Andy Lutomirski

Now vdso/vma.c has a single initcall and no references to
"vsyscall".

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 arch/x86/vdso/vma.c | 61 +++++++++++++++++++----------------------------------
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 8973b4e..84df79b 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -1,7 +1,8 @@
 /*
- * Set up the VMAs to tell the VM about the vDSO.
  * Copyright 2007 Andi Kleen, SUSE Labs.
  * Subject to the GPL, v.2
+ *
+ * This contains most of the x86 vDSO kernel-side code.
  */
 #include <linux/mm.h>
 #include <linux/err.h>
@@ -11,7 +12,6 @@
 #include <linux/random.h>
 #include <linux/elf.h>
 #include <linux/cpu.h>
-#include <asm/vsyscall.h>
 #include <asm/vgtod.h>
 #include <asm/proto.h>
 #include <asm/vdso.h>
@@ -22,8 +22,6 @@
 
 #if defined(CONFIG_X86_64)
 unsigned int __read_mostly vdso64_enabled = 1;
-
-extern unsigned short vdso_sync_cpuid;
 #endif
 
 void __init init_vdso_image(const struct vdso_image *image)
@@ -41,20 +39,6 @@ void __init init_vdso_image(const struct vdso_image *image)
 						image->alt_len));
 }
 
-#if defined(CONFIG_X86_64)
-static int __init init_vdso(void)
-{
-	init_vdso_image(&vdso_image_64);
-
-#ifdef CONFIG_X86_X32_ABI
-	init_vdso_image(&vdso_image_x32);
-#endif
-
-	return 0;
-}
-subsys_initcall(init_vdso);
-#endif
-
 struct linux_binprm;
 
 /* Put the vdso above the (randomized) stack with another randomized offset.
@@ -237,12 +221,9 @@ __setup("vdso=", vdso_setup);
 #endif
 
 #ifdef CONFIG_X86_64
-/*
- * Assume __initcall executes before all user space. Hopefully kmod
- * doesn't violate that. We'll find out if it does.
- */
-static void vsyscall_set_cpu(int cpu)
+static void vgetcpu_cpu_init(void *arg)
 {
+	int cpu = smp_processor_id();
 	unsigned long d;
 	unsigned long node = 0;
 #ifdef CONFIG_NUMA
@@ -252,45 +233,47 @@ static void vsyscall_set_cpu(int cpu)
 		write_rdtscp_aux((node << 12) | cpu);
 
 	/*
-	 * Store cpu number in limit so that it can be loaded quickly
-	 * in user space in vgetcpu. (12 bits for the CPU and 8 bits for the node)
+	 * Store cpu number in limit so that it can be loaded quickly in
+	 * user space in vgetcpu. (12 bits for the CPU and 8 bits for
+	 * the node)
 	 */
 	d = 0x0f40000000000ULL;
 	d |= cpu;
 	d |= (node & 0xf) << 12;
 	d |= (node >> 4) << 48;
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
-}
-
-static void cpu_vsyscall_init(void *arg)
-{
-	/* preemption should be already off */
-	vsyscall_set_cpu(raw_smp_processor_id());
+	write_gdt_entry(get_cpu_gdt_table(cpu),
+			GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int
-cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
+vgetcpu_cpu_notifier(struct notifier_block *n, unsigned long action, void *arg)
 {
 	long cpu = (long)arg;
 
 	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
-		smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 1);
+		smp_call_function_single(cpu, vgetcpu_cpu_init, NULL, 1);
 
 	return NOTIFY_DONE;
 }
 
-static int __init vsyscall_init(void)
+static int __init init_vdso(void)
 {
+	init_vdso_image(&vdso_image_64);
+
+#ifdef CONFIG_X86_X32_ABI
+	init_vdso_image(&vdso_image_x32);
+#endif
+
 	cpu_notifier_register_begin();
 
-	on_each_cpu(cpu_vsyscall_init, NULL, 1);
+	on_each_cpu(vgetcpu_cpu_init, NULL, 1);
 	/* notifier priority > KVM */
-	__hotcpu_notifier(cpu_vsyscall_notifier, 30);
+	__hotcpu_notifier(vgetcpu_cpu_notifier, 30);
 
 	cpu_notifier_register_done();
 
 	return 0;
 }
-__initcall(vsyscall_init);
-#endif
+subsys_initcall(init_vdso);
+#endif /* CONFIG_X86_64 */
-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-06-17  2:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-17  2:23 [PATCH 0/8] x86: vdso and vsyscall round 1 for 3.17 Andy Lutomirski
2014-06-17  2:23 ` [PATCH 1/8] x86_64,vsyscall: Fix warn_bad_vsyscall log output Andy Lutomirski
2014-06-17  2:23 ` [PATCH 2/8] x86_64,vsyscall: Move all of the gate_area code to vsyscall_64.c Andy Lutomirski
2014-06-17  2:23 ` [PATCH 3/8] x86_64,vsyscall: Turn vsyscalls all the way off when vsyscall=none Andy Lutomirski
2014-06-17  2:23 ` [PATCH 4/8] x86_64,vdso: Remove jiffies from the vvar page Andy Lutomirski
2014-06-17  2:23 ` [PATCH 5/8] x86,vdso: Replace vgetcpu_mode with static_cpu_has Andy Lutomirski
2014-06-17  2:23 ` [PATCH 6/8] x86_64: Move getcpu code from vsyscall_64.c to vdso/vma.c Andy Lutomirski
2014-06-17  2:23 ` [PATCH 7/8] x86_64,vsyscall: Rewrite comment and clean up headers in vsyscall code Andy Lutomirski
2014-06-17  2:23 ` [PATCH 8/8] x86_64,vdso: Clean up vgetcpu init and merge the vdso initcalls Andy Lutomirski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®