aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-x86_64')
-rw-r--r--arch/um/sys-x86_64/asm/archparam.h26
-rw-r--r--arch/um/sys-x86_64/asm/elf.h119
-rw-r--r--arch/um/sys-x86_64/asm/module.h30
-rw-r--r--arch/um/sys-x86_64/asm/processor.h56
-rw-r--r--arch/um/sys-x86_64/asm/ptrace.h72
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/archsetjmp.h24
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/barrier.h7
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/checksum.h144
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/faultinfo.h29
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/host_ldt.h38
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h23
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/ptrace.h239
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/ptrace_user.h77
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/sc.h45
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/sigcontext.h27
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h22
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/stub.h107
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/syscalls.h33
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/system.h132
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/tls.h29
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/vm-flags.h33
-rw-r--r--arch/um/sys-x86_64/stub.S1
-rw-r--r--arch/um/sys-x86_64/syscall_table.c8
23 files changed, 1316 insertions, 5 deletions
diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h
new file mode 100644
index 000000000000..270ed9586b68
--- /dev/null
+++ b/arch/um/sys-x86_64/asm/archparam.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __UM_ARCHPARAM_X86_64_H
8#define __UM_ARCHPARAM_X86_64_H
9
10
11/* No user-accessible fixmap addresses, i.e. vsyscall */
12#define FIXADDR_USER_START 0
13#define FIXADDR_USER_END 0
14
15#endif
16
17/*
18 * Overrides for Emacs so that we follow Linus's tabbing style.
19 * Emacs will notice this stuff at the end of the file and automatically
20 * adjust the settings for this buffer only. This must remain at the end
21 * of the file.
22 * ---------------------------------------------------------------------------
23 * Local variables:
24 * c-file-style: "linux"
25 * End:
26 */
diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h
new file mode 100644
index 000000000000..6e8a9195e952
--- /dev/null
+++ b/arch/um/sys-x86_64/asm/elf.h
@@ -0,0 +1,119 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 *
5 * Licensed under the GPL
6 */
7#ifndef __UM_ELF_X86_64_H
8#define __UM_ELF_X86_64_H
9
10#include <asm/user.h>
11#include "skas.h"
12
13/* x86-64 relocation types, taken from asm-x86_64/elf.h */
14#define R_X86_64_NONE 0 /* No reloc */
15#define R_X86_64_64 1 /* Direct 64 bit */
16#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
17#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
18#define R_X86_64_PLT32 4 /* 32 bit PLT address */
19#define R_X86_64_COPY 5 /* Copy symbol at runtime */
20#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
21#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
22#define R_X86_64_RELATIVE 8 /* Adjust by program base */
23#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
24 offset to GOT */
25#define R_X86_64_32 10 /* Direct 32 bit zero extended */
26#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
27#define R_X86_64_16 12 /* Direct 16 bit zero extended */
28#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
29#define R_X86_64_8 14 /* Direct 8 bit sign extended */
30#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
31
32#define R_X86_64_NUM 16
33
34typedef unsigned long elf_greg_t;
35
36#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
37typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38
39typedef struct user_i387_struct elf_fpregset_t;
40
41/*
42 * This is used to ensure we don't load something for the wrong architecture.
43 */
44#define elf_check_arch(x) \
45 ((x)->e_machine == EM_X86_64)
46
47#define ELF_CLASS ELFCLASS64
48#define ELF_DATA ELFDATA2LSB
49#define ELF_ARCH EM_X86_64
50
51#define ELF_PLAT_INIT(regs, load_addr) do { \
52 PT_REGS_RBX(regs) = 0; \
53 PT_REGS_RCX(regs) = 0; \
54 PT_REGS_RDX(regs) = 0; \
55 PT_REGS_RSI(regs) = 0; \
56 PT_REGS_RDI(regs) = 0; \
57 PT_REGS_RBP(regs) = 0; \
58 PT_REGS_RAX(regs) = 0; \
59 PT_REGS_R8(regs) = 0; \
60 PT_REGS_R9(regs) = 0; \
61 PT_REGS_R10(regs) = 0; \
62 PT_REGS_R11(regs) = 0; \
63 PT_REGS_R12(regs) = 0; \
64 PT_REGS_R13(regs) = 0; \
65 PT_REGS_R14(regs) = 0; \
66 PT_REGS_R15(regs) = 0; \
67} while (0)
68
69#define ELF_CORE_COPY_REGS(pr_reg, regs) \
70 (pr_reg)[0] = (regs)->regs.gp[0]; \
71 (pr_reg)[1] = (regs)->regs.gp[1]; \
72 (pr_reg)[2] = (regs)->regs.gp[2]; \
73 (pr_reg)[3] = (regs)->regs.gp[3]; \
74 (pr_reg)[4] = (regs)->regs.gp[4]; \
75 (pr_reg)[5] = (regs)->regs.gp[5]; \
76 (pr_reg)[6] = (regs)->regs.gp[6]; \
77 (pr_reg)[7] = (regs)->regs.gp[7]; \
78 (pr_reg)[8] = (regs)->regs.gp[8]; \
79 (pr_reg)[9] = (regs)->regs.gp[9]; \
80 (pr_reg)[10] = (regs)->regs.gp[10]; \
81 (pr_reg)[11] = (regs)->regs.gp[11]; \
82 (pr_reg)[12] = (regs)->regs.gp[12]; \
83 (pr_reg)[13] = (regs)->regs.gp[13]; \
84 (pr_reg)[14] = (regs)->regs.gp[14]; \
85 (pr_reg)[15] = (regs)->regs.gp[15]; \
86 (pr_reg)[16] = (regs)->regs.gp[16]; \
87 (pr_reg)[17] = (regs)->regs.gp[17]; \
88 (pr_reg)[18] = (regs)->regs.gp[18]; \
89 (pr_reg)[19] = (regs)->regs.gp[19]; \
90 (pr_reg)[20] = (regs)->regs.gp[20]; \
91 (pr_reg)[21] = current->thread.arch.fs; \
92 (pr_reg)[22] = 0; \
93 (pr_reg)[23] = 0; \
94 (pr_reg)[24] = 0; \
95 (pr_reg)[25] = 0; \
96 (pr_reg)[26] = 0;
97
98extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
99
100#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)
101
102#ifdef TIF_IA32 /* XXX */
103#error XXX, indeed
104 clear_thread_flag(TIF_IA32);
105#endif
106
107#define USE_ELF_CORE_DUMP
108#define ELF_EXEC_PAGESIZE 4096
109
110#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
111
112extern long elf_aux_hwcap;
113#define ELF_HWCAP (elf_aux_hwcap)
114
115#define ELF_PLATFORM "x86_64"
116
117#define SET_PERSONALITY(ex) do ; while(0)
118
119#endif
diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h
new file mode 100644
index 000000000000..35b5491d3e96
--- /dev/null
+++ b/arch/um/sys-x86_64/asm/module.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __UM_MODULE_X86_64_H
8#define __UM_MODULE_X86_64_H
9
10/* UML is simple */
11struct mod_arch_specific
12{
13};
14
15#define Elf_Shdr Elf64_Shdr
16#define Elf_Sym Elf64_Sym
17#define Elf_Ehdr Elf64_Ehdr
18
19#endif
20
21/*
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/sys-x86_64/asm/processor.h b/arch/um/sys-x86_64/asm/processor.h
new file mode 100644
index 000000000000..875a26a62614
--- /dev/null
+++ b/arch/um/sys-x86_64/asm/processor.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __UM_PROCESSOR_X86_64_H
8#define __UM_PROCESSOR_X86_64_H
9
10/* include faultinfo structure */
11#include "sysdep/faultinfo.h"
12
13struct arch_thread {
14 unsigned long debugregs[8];
15 int debugregs_seq;
16 unsigned long fs;
17 struct faultinfo faultinfo;
18};
19
20/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
21static inline void rep_nop(void)
22{
23 __asm__ __volatile__("rep;nop": : :"memory");
24}
25
26#define cpu_relax() rep_nop()
27
28#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
29 .debugregs_seq = 0, \
30 .fs = 0, \
31 .faultinfo = { 0, 0, 0 } }
32
33static inline void arch_flush_thread(struct arch_thread *thread)
34{
35}
36
37static inline void arch_copy_thread(struct arch_thread *from,
38 struct arch_thread *to)
39{
40 to->fs = from->fs;
41}
42
43#include <asm/user.h>
44
45#define current_text_addr() \
46 ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
47
48#define ARCH_IS_STACKGROW(address) \
49 (address + 128 >= UPT_SP(&current->thread.regs.regs))
50
51#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP)
52#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP)
53
54#include "asm/processor-generic.h"
55
56#endif
diff --git a/arch/um/sys-x86_64/asm/ptrace.h b/arch/um/sys-x86_64/asm/ptrace.h
new file mode 100644
index 000000000000..83d8c473b905
--- /dev/null
+++ b/arch/um/sys-x86_64/asm/ptrace.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __UM_PTRACE_X86_64_H
8#define __UM_PTRACE_X86_64_H
9
10#include "linux/compiler.h"
11#include "asm/errno.h"
12
13#define __FRAME_OFFSETS /* Needed to get the R* macros */
14#include "asm/ptrace-generic.h"
15
16#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
17
18#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs)
19#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs)
20#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs)
21#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs)
22#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs)
23#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs)
24#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs)
25#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
26#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
27#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
28#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
29#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
30#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
31#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
32#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
33
34#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
35#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
36#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
37#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
38#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
39#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
40
41#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs)
42#define PT_REGS_RIP(r) UPT_IP(&(r)->regs)
43#define PT_REGS_RSP(r) UPT_SP(&(r)->regs)
44
45#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
46
47/* XXX */
48#define user_mode(r) UPT_IS_USER(&(r)->regs)
49#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r)
50#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r)
51
52#define PT_FIX_EXEC_STACK(sp) do ; while(0)
53
54#define profile_pc(regs) PT_REGS_IP(regs)
55
56struct user_desc;
57
58static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
59 struct user_desc __user *user_desc)
60{
61 return -ENOSYS;
62}
63
64static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
65 struct user_desc __user *user_desc)
66{
67 return -ENOSYS;
68}
69
70extern long arch_prctl(struct task_struct *task, int code,
71 unsigned long __user *addr);
72#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h b/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h
new file mode 100644
index 000000000000..2af8f12ca161
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h
@@ -0,0 +1,24 @@
1/*
2 * arch/um/include/sysdep-x86_64/archsetjmp.h
3 */
4
5#ifndef _KLIBC_ARCHSETJMP_H
6#define _KLIBC_ARCHSETJMP_H
7
8struct __jmp_buf {
9 unsigned long __rbx;
10 unsigned long __rsp;
11 unsigned long __rbp;
12 unsigned long __r12;
13 unsigned long __r13;
14 unsigned long __r14;
15 unsigned long __r15;
16 unsigned long __rip;
17};
18
19typedef struct __jmp_buf jmp_buf[1];
20
21#define JB_IP __rip
22#define JB_SP __rsp
23
24#endif /* _SETJMP_H */
diff --git a/arch/um/sys-x86_64/shared/sysdep/barrier.h b/arch/um/sys-x86_64/shared/sysdep/barrier.h
new file mode 100644
index 000000000000..7b610befdc8f
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/barrier.h
@@ -0,0 +1,7 @@
1#ifndef __SYSDEP_X86_64_BARRIER_H
2#define __SYSDEP_X86_64_BARRIER_H
3
4/* Copied from include/asm-x86_64 for use by userspace. */
5#define mb() asm volatile("mfence":::"memory")
6
7#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/checksum.h b/arch/um/sys-x86_64/shared/sysdep/checksum.h
new file mode 100644
index 000000000000..a5be9031ea85
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/checksum.h
@@ -0,0 +1,144 @@
1/*
2 * Licensed under the GPL
3 */
4
5#ifndef __UM_SYSDEP_CHECKSUM_H
6#define __UM_SYSDEP_CHECKSUM_H
7
8#include "linux/string.h"
9#include "linux/in6.h"
10#include "asm/uaccess.h"
11
12extern __wsum csum_partial(const void *buff, int len, __wsum sum);
13
14/*
15 * Note: when you get a NULL pointer exception here this means someone
16 * passed in an incorrect kernel address to one of these functions.
17 *
18 * If you use these functions directly please don't forget the
19 * access_ok().
20 */
21
22static __inline__
23__wsum csum_partial_copy_nocheck(const void *src, void *dst,
24 int len, __wsum sum)
25{
26 memcpy(dst, src, len);
27 return(csum_partial(dst, len, sum));
28}
29
30static __inline__
31__wsum csum_partial_copy_from_user(const void __user *src,
32 void *dst, int len, __wsum sum,
33 int *err_ptr)
34{
35 if (copy_from_user(dst, src, len)) {
36 *err_ptr = -EFAULT;
37 return (__force __wsum)-1;
38 }
39 return csum_partial(dst, len, sum);
40}
41
42/**
43 * csum_fold - Fold and invert a 32bit checksum.
44 * sum: 32bit unfolded sum
45 *
46 * Fold a 32bit running checksum to 16bit and invert it. This is usually
47 * the last step before putting a checksum into a packet.
48 * Make sure not to mix with 64bit checksums.
49 */
50static inline __sum16 csum_fold(__wsum sum)
51{
52 __asm__(
53 " addl %1,%0\n"
54 " adcl $0xffff,%0"
55 : "=r" (sum)
56 : "r" ((__force u32)sum << 16),
57 "0" ((__force u32)sum & 0xffff0000)
58 );
59 return (__force __sum16)(~(__force u32)sum >> 16);
60}
61
62/**
63 * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
64 * @saddr: source address
65 * @daddr: destination address
66 * @len: length of packet
67 * @proto: ip protocol of packet
68 * @sum: initial sum to be added in (32bit unfolded)
69 *
70 * Returns the pseudo header checksum the input data. Result is
71 * 32bit unfolded.
72 */
73static inline __wsum
74csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
75 unsigned short proto, __wsum sum)
76{
77 asm(" addl %1, %0\n"
78 " adcl %2, %0\n"
79 " adcl %3, %0\n"
80 " adcl $0, %0\n"
81 : "=r" (sum)
82 : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
83 return sum;
84}
85
86/*
87 * computes the checksum of the TCP/UDP pseudo-header
88 * returns a 16-bit checksum, already complemented
89 */
90static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
91 unsigned short len,
92 unsigned short proto,
93 __wsum sum)
94{
95 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
96}
97
98/**
99 * ip_fast_csum - Compute the IPv4 header checksum efficiently.
100 * iph: ipv4 header
101 * ihl: length of header / 4
102 */
103static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
104{
105 unsigned int sum;
106
107 asm( " movl (%1), %0\n"
108 " subl $4, %2\n"
109 " jbe 2f\n"
110 " addl 4(%1), %0\n"
111 " adcl 8(%1), %0\n"
112 " adcl 12(%1), %0\n"
113 "1: adcl 16(%1), %0\n"
114 " lea 4(%1), %1\n"
115 " decl %2\n"
116 " jne 1b\n"
117 " adcl $0, %0\n"
118 " movl %0, %2\n"
119 " shrl $16, %0\n"
120 " addw %w2, %w0\n"
121 " adcl $0, %0\n"
122 " notl %0\n"
123 "2:"
124 /* Since the input registers which are loaded with iph and ipl
125 are modified, we must also specify them as outputs, or gcc
126 will assume they contain their original values. */
127 : "=r" (sum), "=r" (iph), "=r" (ihl)
128 : "1" (iph), "2" (ihl)
129 : "memory");
130 return (__force __sum16)sum;
131}
132
133static inline unsigned add32_with_carry(unsigned a, unsigned b)
134{
135 asm("addl %2,%0\n\t"
136 "adcl $0,%0"
137 : "=r" (a)
138 : "0" (a), "r" (b));
139 return a;
140}
141
142extern __sum16 ip_compute_csum(const void *buff, int len);
143
144#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h b/arch/um/sys-x86_64/shared/sysdep/faultinfo.h
new file mode 100644
index 000000000000..cb917b0d5660
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/faultinfo.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
4 * Licensed under the GPL
5 */
6
7#ifndef __FAULTINFO_X86_64_H
8#define __FAULTINFO_X86_64_H
9
10/* this structure contains the full arch-specific faultinfo
11 * from the traps.
12 * On i386, ptrace_faultinfo unfortunately doesn't provide
13 * all the info, since trap_no is missing.
14 * All common elements are defined at the same position in
15 * both structures, thus making it easy to copy the
16 * contents without knowledge about the structure elements.
17 */
18struct faultinfo {
19 int error_code; /* in ptrace_faultinfo misleadingly called is_write */
20 unsigned long cr2; /* in ptrace_faultinfo called addr */
21 int trap_no; /* missing in ptrace_faultinfo */
22};
23
24#define FAULT_WRITE(fi) ((fi).error_code & 2)
25#define FAULT_ADDRESS(fi) ((fi).cr2)
26
27#define PTRACE_FULL_FAULTINFO 1
28
29#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h b/arch/um/sys-x86_64/shared/sysdep/host_ldt.h
new file mode 100644
index 000000000000..e8b1be1e154f
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/host_ldt.h
@@ -0,0 +1,38 @@
1#ifndef __ASM_HOST_LDT_X86_64_H
2#define __ASM_HOST_LDT_X86_64_H
3
4#include <asm/ldt.h>
5
6/*
7 * macros stolen from include/asm-x86_64/desc.h
8 */
9#define LDT_entry_a(info) \
10 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
11
12/* Don't allow setting of the lm bit. It is useless anyways because
13 * 64bit system calls require __USER_CS. */
14#define LDT_entry_b(info) \
15 (((info)->base_addr & 0xff000000) | \
16 (((info)->base_addr & 0x00ff0000) >> 16) | \
17 ((info)->limit & 0xf0000) | \
18 (((info)->read_exec_only ^ 1) << 9) | \
19 ((info)->contents << 10) | \
20 (((info)->seg_not_present ^ 1) << 15) | \
21 ((info)->seg_32bit << 22) | \
22 ((info)->limit_in_pages << 23) | \
23 ((info)->useable << 20) | \
24 /* ((info)->lm << 21) | */ \
25 0x7000)
26
27#define LDT_empty(info) (\
28 (info)->base_addr == 0 && \
29 (info)->limit == 0 && \
30 (info)->contents == 0 && \
31 (info)->read_exec_only == 1 && \
32 (info)->seg_32bit == 0 && \
33 (info)->limit_in_pages == 0 && \
34 (info)->seg_not_present == 1 && \
35 (info)->useable == 0 && \
36 (info)->lm == 0)
37
38#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h
new file mode 100644
index 000000000000..a307237b7964
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h
@@ -0,0 +1,23 @@
1#include <linux/stddef.h>
2#include <linux/sched.h>
3#include <linux/time.h>
4#include <linux/elf.h>
5#include <linux/crypto.h>
6#include <asm/page.h>
7#include <asm/mman.h>
8
9#define DEFINE(sym, val) \
10 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
11
12#define DEFINE_STR1(x) #x
13#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : )
14
15#define BLANK() asm volatile("\n->" : : )
16
17#define OFFSET(sym, str, mem) \
18 DEFINE(sym, offsetof(struct str, mem));
19
20void foo(void)
21{
22#include <common-offsets.h>
23}
diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
new file mode 100644
index 000000000000..fdba5457947a
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
@@ -0,0 +1,239 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 *
5 * Licensed under the GPL
6 */
7
8#ifndef __SYSDEP_X86_64_PTRACE_H
9#define __SYSDEP_X86_64_PTRACE_H
10
11#include "user_constants.h"
12#include "sysdep/faultinfo.h"
13
14#define MAX_REG_OFFSET (UM_FRAME_SIZE)
15#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
16
17#include "skas_ptregs.h"
18
19#define REGS_IP(r) ((r)[HOST_IP])
20#define REGS_SP(r) ((r)[HOST_SP])
21
22#define REGS_RBX(r) ((r)[HOST_RBX])
23#define REGS_RCX(r) ((r)[HOST_RCX])
24#define REGS_RDX(r) ((r)[HOST_RDX])
25#define REGS_RSI(r) ((r)[HOST_RSI])
26#define REGS_RDI(r) ((r)[HOST_RDI])
27#define REGS_RBP(r) ((r)[HOST_RBP])
28#define REGS_RAX(r) ((r)[HOST_RAX])
29#define REGS_R8(r) ((r)[HOST_R8])
30#define REGS_R9(r) ((r)[HOST_R9])
31#define REGS_R10(r) ((r)[HOST_R10])
32#define REGS_R11(r) ((r)[HOST_R11])
33#define REGS_R12(r) ((r)[HOST_R12])
34#define REGS_R13(r) ((r)[HOST_R13])
35#define REGS_R14(r) ((r)[HOST_R14])
36#define REGS_R15(r) ((r)[HOST_R15])
37#define REGS_CS(r) ((r)[HOST_CS])
38#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
39#define REGS_SS(r) ((r)[HOST_SS])
40
41#define HOST_FS_BASE 21
42#define HOST_GS_BASE 22
43#define HOST_DS 23
44#define HOST_ES 24
45#define HOST_FS 25
46#define HOST_GS 26
47
48/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these
49 * are already defined for kernel code, but not for userspace code.
50 */
51#ifndef FS_BASE
52/* These aren't defined in ptrace.h, but exist in struct user_regs_struct,
53 * which is what x86_64 ptrace actually uses.
54 */
55#define FS_BASE (HOST_FS_BASE * sizeof(long))
56#define GS_BASE (HOST_GS_BASE * sizeof(long))
57#define DS (HOST_DS * sizeof(long))
58#define ES (HOST_ES * sizeof(long))
59#define FS (HOST_FS * sizeof(long))
60#define GS (HOST_GS * sizeof(long))
61#endif
62
63#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE])
64#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE])
65#define REGS_DS(r) ((r)[HOST_DS])
66#define REGS_ES(r) ((r)[HOST_ES])
67#define REGS_FS(r) ((r)[HOST_FS])
68#define REGS_GS(r) ((r)[HOST_GS])
69
70#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX])
71
72#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res)
73
74#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
75
76#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
77
78#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
79
80#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
81
82#define REGS_TRAP(r) ((r)->trap_type)
83
84#define REGS_ERR(r) ((r)->fault_type)
85
86struct uml_pt_regs {
87 unsigned long gp[MAX_REG_NR];
88 struct faultinfo faultinfo;
89 long syscall;
90 int is_user;
91};
92
93#define EMPTY_UML_PT_REGS { }
94
95#define UPT_RBX(r) REGS_RBX((r)->gp)
96#define UPT_RCX(r) REGS_RCX((r)->gp)
97#define UPT_RDX(r) REGS_RDX((r)->gp)
98#define UPT_RSI(r) REGS_RSI((r)->gp)
99#define UPT_RDI(r) REGS_RDI((r)->gp)
100#define UPT_RBP(r) REGS_RBP((r)->gp)
101#define UPT_RAX(r) REGS_RAX((r)->gp)
102#define UPT_R8(r) REGS_R8((r)->gp)
103#define UPT_R9(r) REGS_R9((r)->gp)
104#define UPT_R10(r) REGS_R10((r)->gp)
105#define UPT_R11(r) REGS_R11((r)->gp)
106#define UPT_R12(r) REGS_R12((r)->gp)
107#define UPT_R13(r) REGS_R13((r)->gp)
108#define UPT_R14(r) REGS_R14((r)->gp)
109#define UPT_R15(r) REGS_R15((r)->gp)
110#define UPT_CS(r) REGS_CS((r)->gp)
111#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp)
112#define UPT_FS(r) REGS_FS((r)->gp)
113#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp)
114#define UPT_GS(r) REGS_GS((r)->gp)
115#define UPT_DS(r) REGS_DS((r)->gp)
116#define UPT_ES(r) REGS_ES((r)->gp)
117#define UPT_CS(r) REGS_CS((r)->gp)
118#define UPT_SS(r) REGS_SS((r)->gp)
119#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp)
120
121#define UPT_IP(r) REGS_IP((r)->gp)
122#define UPT_SP(r) REGS_SP((r)->gp)
123
124#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp)
125#define UPT_SYSCALL_NR(r) ((r)->syscall)
126#define UPT_SYSCALL_RET(r) UPT_RAX(r)
127
128extern int user_context(unsigned long sp);
129
130#define UPT_IS_USER(r) ((r)->is_user)
131
132#define UPT_SYSCALL_ARG1(r) UPT_RDI(r)
133#define UPT_SYSCALL_ARG2(r) UPT_RSI(r)
134#define UPT_SYSCALL_ARG3(r) UPT_RDX(r)
135#define UPT_SYSCALL_ARG4(r) UPT_R10(r)
136#define UPT_SYSCALL_ARG5(r) UPT_R8(r)
137#define UPT_SYSCALL_ARG6(r) UPT_R9(r)
138
139struct syscall_args {
140 unsigned long args[6];
141};
142
143#define SYSCALL_ARGS(r) ((struct syscall_args) \
144 { .args = { UPT_SYSCALL_ARG1(r), \
145 UPT_SYSCALL_ARG2(r), \
146 UPT_SYSCALL_ARG3(r), \
147 UPT_SYSCALL_ARG4(r), \
148 UPT_SYSCALL_ARG5(r), \
149 UPT_SYSCALL_ARG6(r) } } )
150
151#define UPT_REG(regs, reg) \
152 ({ unsigned long val; \
153 switch(reg){ \
154 case R8: val = UPT_R8(regs); break; \
155 case R9: val = UPT_R9(regs); break; \
156 case R10: val = UPT_R10(regs); break; \
157 case R11: val = UPT_R11(regs); break; \
158 case R12: val = UPT_R12(regs); break; \
159 case R13: val = UPT_R13(regs); break; \
160 case R14: val = UPT_R14(regs); break; \
161 case R15: val = UPT_R15(regs); break; \
162 case RIP: val = UPT_IP(regs); break; \
163 case RSP: val = UPT_SP(regs); break; \
164 case RAX: val = UPT_RAX(regs); break; \
165 case RBX: val = UPT_RBX(regs); break; \
166 case RCX: val = UPT_RCX(regs); break; \
167 case RDX: val = UPT_RDX(regs); break; \
168 case RSI: val = UPT_RSI(regs); break; \
169 case RDI: val = UPT_RDI(regs); break; \
170 case RBP: val = UPT_RBP(regs); break; \
171 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
172 case CS: val = UPT_CS(regs); break; \
173 case SS: val = UPT_SS(regs); break; \
174 case FS_BASE: val = UPT_FS_BASE(regs); break; \
175 case GS_BASE: val = UPT_GS_BASE(regs); break; \
176 case DS: val = UPT_DS(regs); break; \
177 case ES: val = UPT_ES(regs); break; \
178 case FS : val = UPT_FS (regs); break; \
179 case GS: val = UPT_GS(regs); break; \
180 case EFLAGS: val = UPT_EFLAGS(regs); break; \
181 default : \
182 panic("Bad register in UPT_REG : %d\n", reg); \
183 val = -1; \
184 } \
185 val; \
186 })
187
188
189#define UPT_SET(regs, reg, val) \
190 ({ unsigned long __upt_val = val; \
191 switch(reg){ \
192 case R8: UPT_R8(regs) = __upt_val; break; \
193 case R9: UPT_R9(regs) = __upt_val; break; \
194 case R10: UPT_R10(regs) = __upt_val; break; \
195 case R11: UPT_R11(regs) = __upt_val; break; \
196 case R12: UPT_R12(regs) = __upt_val; break; \
197 case R13: UPT_R13(regs) = __upt_val; break; \
198 case R14: UPT_R14(regs) = __upt_val; break; \
199 case R15: UPT_R15(regs) = __upt_val; break; \
200 case RIP: UPT_IP(regs) = __upt_val; break; \
201 case RSP: UPT_SP(regs) = __upt_val; break; \
202 case RAX: UPT_RAX(regs) = __upt_val; break; \
203 case RBX: UPT_RBX(regs) = __upt_val; break; \
204 case RCX: UPT_RCX(regs) = __upt_val; break; \
205 case RDX: UPT_RDX(regs) = __upt_val; break; \
206 case RSI: UPT_RSI(regs) = __upt_val; break; \
207 case RDI: UPT_RDI(regs) = __upt_val; break; \
208 case RBP: UPT_RBP(regs) = __upt_val; break; \
209 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
210 case CS: UPT_CS(regs) = __upt_val; break; \
211 case SS: UPT_SS(regs) = __upt_val; break; \
212 case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
213 case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
214 case DS: UPT_DS(regs) = __upt_val; break; \
215 case ES: UPT_ES(regs) = __upt_val; break; \
216 case FS: UPT_FS(regs) = __upt_val; break; \
217 case GS: UPT_GS(regs) = __upt_val; break; \
218 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
219 default : \
220 panic("Bad register in UPT_SET : %d\n", reg); \
221 break; \
222 } \
223 __upt_val; \
224 })
225
226#define UPT_SET_SYSCALL_RETURN(r, res) \
227 REGS_SET_SYSCALL_RETURN((r)->regs, (res))
228
229#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp)
230
231#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas)
232
233#define UPT_FAULTINFO(r) (&(r)->faultinfo)
234
235static inline void arch_init_registers(int pid)
236{
237}
238
239#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h
new file mode 100644
index 000000000000..4dbccdb58f48
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __SYSDEP_X86_64_PTRACE_USER_H__
8#define __SYSDEP_X86_64_PTRACE_USER_H__
9
10#define __FRAME_OFFSETS
11#include <sys/ptrace.h>
12#include <linux/ptrace.h>
13#include <asm/ptrace.h>
14#undef __FRAME_OFFSETS
15#include "user_constants.h"
16
17#define PT_INDEX(off) ((off) / sizeof(unsigned long))
18
19#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)])
20#define PT_SYSCALL_NR_OFFSET (ORIG_RAX)
21
22#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)])
23#define PT_SYSCALL_ARG1_OFFSET (RDI)
24
25#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)])
26#define PT_SYSCALL_ARG2_OFFSET (RSI)
27
28#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)])
29#define PT_SYSCALL_ARG3_OFFSET (RDX)
30
31#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)])
32#define PT_SYSCALL_ARG4_OFFSET (RCX)
33
34#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)])
35#define PT_SYSCALL_ARG5_OFFSET (R8)
36
37#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)])
38#define PT_SYSCALL_ARG6_OFFSET (R9)
39
40#define PT_SYSCALL_RET_OFFSET (RAX)
41
42#define PT_IP_OFFSET (RIP)
43#define PT_IP(regs) ((regs)[PT_INDEX(RIP)])
44
45#define PT_SP_OFFSET (RSP)
46#define PT_SP(regs) ((regs)[PT_INDEX(RSP)])
47
48#define PT_ORIG_RAX_OFFSET (ORIG_RAX)
49#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
50
51/*
52 * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
53 * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
54 * 2.4 name and value for 2.4 host compatibility.
55 */
56#ifndef PTRACE_OLDSETOPTIONS
57#define PTRACE_OLDSETOPTIONS 21
58#endif
59
60/*
61 * These are before the system call, so the system call number is RAX
62 * rather than ORIG_RAX, and arg4 is R10 rather than RCX
63 */
64#define REGS_SYSCALL_NR PT_INDEX(RAX)
65#define REGS_SYSCALL_ARG1 PT_INDEX(RDI)
66#define REGS_SYSCALL_ARG2 PT_INDEX(RSI)
67#define REGS_SYSCALL_ARG3 PT_INDEX(RDX)
68#define REGS_SYSCALL_ARG4 PT_INDEX(R10)
69#define REGS_SYSCALL_ARG5 PT_INDEX(R8)
70#define REGS_SYSCALL_ARG6 PT_INDEX(R9)
71
72#define REGS_IP_INDEX PT_INDEX(RIP)
73#define REGS_SP_INDEX PT_INDEX(RSP)
74
75#define FP_SIZE (HOST_FP_SIZE)
76
77#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/sc.h b/arch/um/sys-x86_64/shared/sysdep/sc.h
new file mode 100644
index 000000000000..8aee45b07434
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/sc.h
@@ -0,0 +1,45 @@
1#ifndef __SYSDEP_X86_64_SC_H
2#define __SYSDEP_X86_64_SC_H
3
4/* Copyright (C) 2003 - 2004 PathScale, Inc
5 * Released under the GPL
6 */
7
8#include <user_constants.h>
9
10#define SC_OFFSET(sc, field) \
11 *((unsigned long *) &(((char *) (sc))[HOST_##field]))
12
13#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX)
14#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX)
15#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX)
16#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI)
17#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI)
18#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP)
19#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX)
20#define SC_R8(sc) SC_OFFSET(sc, SC_R8)
21#define SC_R9(sc) SC_OFFSET(sc, SC_R9)
22#define SC_R10(sc) SC_OFFSET(sc, SC_R10)
23#define SC_R11(sc) SC_OFFSET(sc, SC_R11)
24#define SC_R12(sc) SC_OFFSET(sc, SC_R12)
25#define SC_R13(sc) SC_OFFSET(sc, SC_R13)
26#define SC_R14(sc) SC_OFFSET(sc, SC_R14)
27#define SC_R15(sc) SC_OFFSET(sc, SC_R15)
28#define SC_IP(sc) SC_OFFSET(sc, SC_IP)
29#define SC_SP(sc) SC_OFFSET(sc, SC_SP)
30#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2)
31#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR)
32#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO)
33#define SC_CS(sc) SC_OFFSET(sc, SC_CS)
34#define SC_FS(sc) SC_OFFSET(sc, SC_FS)
35#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
36#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
37#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
38#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
39#if 0
40#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX)
41#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
42#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
43#endif
44
45#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h
new file mode 100644
index 000000000000..0155133b1458
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __SYSDEP_X86_64_SIGCONTEXT_H
8#define __SYSDEP_X86_64_SIGCONTEXT_H
9
10#include <sysdep/sc.h>
11
12#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
13
14#define GET_FAULTINFO_FROM_SC(fi, sc) \
15 { \
16 (fi).cr2 = SC_CR2(sc); \
17 (fi).error_code = SC_ERR(sc); \
18 (fi).trap_no = SC_TRAPNO(sc); \
19 }
20
21/* This is Page Fault */
22#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
23
24/* No broken SKAS API, which doesn't pass trap_no, here. */
25#define SEGV_MAYBE_FIXABLE(fi) 0
26
27#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h
new file mode 100644
index 000000000000..95db4be786e4
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H
7#define __SYSDEP_X86_64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/stub.h b/arch/um/sys-x86_64/shared/sysdep/stub.h
new file mode 100644
index 000000000000..3432aa249970
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/stub.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_STUB_H
7#define __SYSDEP_STUB_H
8
9#include <sys/mman.h>
10#include <asm/unistd.h>
11#include <sysdep/ptrace_user.h>
12#include "as-layout.h"
13#include "stub-data.h"
14#include "kern_constants.h"
15
16extern void stub_segv_handler(int sig);
17extern void stub_clone_handler(void);
18
19#define STUB_SYSCALL_RET PT_INDEX(RAX)
20#define STUB_MMAP_NR __NR_mmap
21#define MMAP_OFFSET(o) (o)
22
23#define __syscall_clobber "r11","rcx","memory"
24#define __syscall "syscall"
25
26static inline long stub_syscall0(long syscall)
27{
28 long ret;
29
30 __asm__ volatile (__syscall
31 : "=a" (ret)
32 : "0" (syscall) : __syscall_clobber );
33
34 return ret;
35}
36
37static inline long stub_syscall2(long syscall, long arg1, long arg2)
38{
39 long ret;
40
41 __asm__ volatile (__syscall
42 : "=a" (ret)
43 : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber );
44
45 return ret;
46}
47
48static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
49{
50 long ret;
51
52 __asm__ volatile (__syscall
53 : "=a" (ret)
54 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3)
55 : __syscall_clobber );
56
57 return ret;
58}
59
60static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
61 long arg4)
62{
63 long ret;
64
65 __asm__ volatile ("movq %5,%%r10 ; " __syscall
66 : "=a" (ret)
67 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
68 "g" (arg4)
69 : __syscall_clobber, "r10" );
70
71 return ret;
72}
73
74static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
75 long arg4, long arg5)
76{
77 long ret;
78
79 __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall
80 : "=a" (ret)
81 : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
82 "g" (arg4), "g" (arg5)
83 : __syscall_clobber, "r10", "r8" );
84
85 return ret;
86}
87
88static inline void trap_myself(void)
89{
90 __asm("int3");
91}
92
93static inline void remap_stack(long fd, unsigned long offset)
94{
95 __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; "
96 "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; "
97 "movq %%rax, (%%rbx)":
98 : "a" (STUB_MMAP_NR), "D" (STUB_DATA),
99 "S" (UM_KERN_PAGE_SIZE),
100 "d" (PROT_READ | PROT_WRITE),
101 "g" (MAP_FIXED | MAP_SHARED), "g" (fd),
102 "g" (offset),
103 "i" (&((struct stub_data *) STUB_DATA)->err)
104 : __syscall_clobber, "r10", "r8", "r9" );
105}
106
107#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/syscalls.h b/arch/um/sys-x86_64/shared/sysdep/syscalls.h
new file mode 100644
index 000000000000..7cfb0b085655
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/syscalls.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#ifndef __SYSDEP_X86_64_SYSCALLS_H__
8#define __SYSDEP_X86_64_SYSCALLS_H__
9
10#include <linux/msg.h>
11#include <linux/shm.h>
12#include <kern_constants.h>
13
14typedef long syscall_handler_t(void);
15
16extern syscall_handler_t *sys_call_table[];
17
18#define EXECUTE_SYSCALL(syscall, regs) \
19 (((long (*)(long, long, long, long, long, long)) \
20 (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(&regs->regs), \
21 UPT_SYSCALL_ARG2(&regs->regs), \
22 UPT_SYSCALL_ARG3(&regs->regs), \
23 UPT_SYSCALL_ARG4(&regs->regs), \
24 UPT_SYSCALL_ARG5(&regs->regs), \
25 UPT_SYSCALL_ARG6(&regs->regs)))
26
27extern long old_mmap(unsigned long addr, unsigned long len,
28 unsigned long prot, unsigned long flags,
29 unsigned long fd, unsigned long pgoff);
30extern syscall_handler_t sys_modify_ldt;
31extern syscall_handler_t sys_arch_prctl;
32
33#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/system.h b/arch/um/sys-x86_64/shared/sysdep/system.h
new file mode 100644
index 000000000000..d1b93c436200
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/system.h
@@ -0,0 +1,132 @@
1#ifndef _ASM_X86_SYSTEM_H_
2#define _ASM_X86_SYSTEM_H_
3
4#include <asm/asm.h>
5#include <asm/segment.h>
6#include <asm/cpufeature.h>
7#include <asm/cmpxchg.h>
8#include <asm/nops.h>
9
10#include <linux/kernel.h>
11#include <linux/irqflags.h>
12
13/* entries in ARCH_DLINFO: */
14#ifdef CONFIG_IA32_EMULATION
15# define AT_VECTOR_SIZE_ARCH 2
16#else
17# define AT_VECTOR_SIZE_ARCH 1
18#endif
19
20extern unsigned long arch_align_stack(unsigned long sp);
21
22void default_idle(void);
23
24/*
25 * Force strict CPU ordering.
26 * And yes, this is required on UP too when we're talking
27 * to devices.
28 */
29#ifdef CONFIG_X86_32
30/*
31 * Some non-Intel clones support out of order store. wmb() ceases to be a
32 * nop for these.
33 */
34#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
35#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
36#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
37#else
38#define mb() asm volatile("mfence":::"memory")
39#define rmb() asm volatile("lfence":::"memory")
40#define wmb() asm volatile("sfence" ::: "memory")
41#endif
42
43/**
44 * read_barrier_depends - Flush all pending reads that subsequents reads
45 * depend on.
46 *
47 * No data-dependent reads from memory-like regions are ever reordered
48 * over this barrier. All reads preceding this primitive are guaranteed
49 * to access memory (but not necessarily other CPUs' caches) before any
50 * reads following this primitive that depend on the data return by
51 * any of the preceding reads. This primitive is much lighter weight than
52 * rmb() on most CPUs, and is never heavier weight than is
53 * rmb().
54 *
55 * These ordering constraints are respected by both the local CPU
56 * and the compiler.
57 *
58 * Ordering is not guaranteed by anything other than these primitives,
59 * not even by data dependencies. See the documentation for
60 * memory_barrier() for examples and URLs to more information.
61 *
62 * For example, the following code would force ordering (the initial
63 * value of "a" is zero, "b" is one, and "p" is "&a"):
64 *
65 * <programlisting>
66 * CPU 0 CPU 1
67 *
68 * b = 2;
69 * memory_barrier();
70 * p = &b; q = p;
71 * read_barrier_depends();
72 * d = *q;
73 * </programlisting>
74 *
75 * because the read of "*q" depends on the read of "p" and these
76 * two reads are separated by a read_barrier_depends(). However,
77 * the following code, with the same initial values for "a" and "b":
78 *
79 * <programlisting>
80 * CPU 0 CPU 1
81 *
82 * a = 2;
83 * memory_barrier();
84 * b = 3; y = b;
85 * read_barrier_depends();
86 * x = a;
87 * </programlisting>
88 *
89 * does not enforce ordering, since there is no data dependency between
90 * the read of "a" and the read of "b". Therefore, on some CPUs, such
91 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
92 * in cases like this where there are no data dependencies.
93 **/
94
95#define read_barrier_depends() do { } while (0)
96
97#ifdef CONFIG_SMP
98#define smp_mb() mb()
99#ifdef CONFIG_X86_PPRO_FENCE
100# define smp_rmb() rmb()
101#else
102# define smp_rmb() barrier()
103#endif
104#ifdef CONFIG_X86_OOSTORE
105# define smp_wmb() wmb()
106#else
107# define smp_wmb() barrier()
108#endif
109#define smp_read_barrier_depends() read_barrier_depends()
110#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
111#else
112#define smp_mb() barrier()
113#define smp_rmb() barrier()
114#define smp_wmb() barrier()
115#define smp_read_barrier_depends() do { } while (0)
116#define set_mb(var, value) do { var = value; barrier(); } while (0)
117#endif
118
119/*
120 * Stop RDTSC speculation. This is needed when you need to use RDTSC
121 * (or get_cycles or vread that possibly accesses the TSC) in a defined
122 * code region.
123 *
124 * (Could use an alternative three way for this if there was one.)
125 */
126static inline void rdtsc_barrier(void)
127{
128 alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
129 alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
130}
131
132#endif
diff --git a/arch/um/sys-x86_64/shared/sysdep/tls.h b/arch/um/sys-x86_64/shared/sysdep/tls.h
new file mode 100644
index 000000000000..18c000d0357a
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/tls.h
@@ -0,0 +1,29 @@
1#ifndef _SYSDEP_TLS_H
2#define _SYSDEP_TLS_H
3
4# ifndef __KERNEL__
5
6/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
7 * may be named user_desc (but in 2.4 and in header matching its API was named
8 * modify_ldt_ldt_s). */
9
10typedef struct um_dup_user_desc {
11 unsigned int entry_number;
12 unsigned int base_addr;
13 unsigned int limit;
14 unsigned int seg_32bit:1;
15 unsigned int contents:2;
16 unsigned int read_exec_only:1;
17 unsigned int limit_in_pages:1;
18 unsigned int seg_not_present:1;
19 unsigned int useable:1;
20 unsigned int lm:1;
21} user_desc_t;
22
23# else /* __KERNEL__ */
24
25# include <ldt.h>
26typedef struct user_desc user_desc_t;
27
28# endif /* __KERNEL__ */
29#endif /* _SYSDEP_TLS_H */
diff --git a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h
new file mode 100644
index 000000000000..3213edfa7888
--- /dev/null
+++ b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#ifndef __VM_FLAGS_X86_64_H
8#define __VM_FLAGS_X86_64_H
9
10#define __VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
11 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
12#define __VM_STACK_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \
13 VM_EXEC | VM_MAYREAD | VM_MAYWRITE | \
14 VM_MAYEXEC)
15
16extern unsigned long vm_stack_flags, vm_stack_flags32;
17extern unsigned long vm_data_default_flags, vm_data_default_flags32;
18extern unsigned long vm_force_exec32;
19
20#ifdef TIF_IA32
21#define VM_DATA_DEFAULT_FLAGS \
22 (test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \
23 vm_data_default_flags)
24
25#define VM_STACK_DEFAULT_FLAGS \
26 (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags)
27#endif
28
29#define VM_DATA_DEFAULT_FLAGS vm_data_default_flags
30
31#define VM_STACK_DEFAULT_FLAGS vm_stack_flags
32
33#endif
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
index 568768763155..6d9edf9fabce 100644
--- a/arch/um/sys-x86_64/stub.S
+++ b/arch/um/sys-x86_64/stub.S
@@ -1,4 +1,3 @@
1#include "uml-config.h"
2#include "as-layout.h" 1#include "as-layout.h"
3 2
4 .globl syscall_stub 3 .globl syscall_stub
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
index c128eb897008..dd21d69715e6 100644
--- a/arch/um/sys-x86_64/syscall_table.c
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -41,12 +41,12 @@
41#define stub_rt_sigreturn sys_rt_sigreturn 41#define stub_rt_sigreturn sys_rt_sigreturn
42 42
43#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; 43#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
44#undef _ASM_X86_64_UNISTD_H_ 44#undef _ASM_X86_UNISTD_64_H
45#include <asm-x86/unistd_64.h> 45#include "../../x86/include/asm/unistd_64.h"
46 46
47#undef __SYSCALL 47#undef __SYSCALL
48#define __SYSCALL(nr, sym) [ nr ] = sym, 48#define __SYSCALL(nr, sym) [ nr ] = sym,
49#undef _ASM_X86_64_UNISTD_H_ 49#undef _ASM_X86_UNISTD_64_H
50 50
51typedef void (*sys_call_ptr_t)(void); 51typedef void (*sys_call_ptr_t)(void);
52 52
@@ -64,7 +64,7 @@ extern void sys_ni_syscall(void);
64 */ 64 */
65 65
66sys_call_ptr_t sys_call_table[] __cacheline_aligned = { 66sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
67#include <asm-x86/unistd_64.h> 67#include "../../x86/include/asm/unistd_64.h"
68}; 68};
69 69
70int syscall_table_size = sizeof(sys_call_table); 70int syscall_table_size = sizeof(sys_call_table);