diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/Makefile | 2 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/stub.h | 9 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/stub.h | 12 | ||||
-rw-r--r-- | arch/um/kernel/skas/clone.c | 21 | ||||
-rw-r--r-- | arch/um/sys-i386/Makefile | 2 | ||||
-rw-r--r-- | arch/um/sys-i386/ldt.c | 35 | ||||
-rw-r--r-- | arch/um/sys-i386/stub_segv.c | 11 | ||||
-rw-r--r-- | arch/um/sys-x86_64/Makefile | 2 | ||||
-rw-r--r-- | arch/um/sys-x86_64/stub_segv.c | 20 |
9 files changed, 73 insertions, 41 deletions
diff --git a/arch/um/Makefile b/arch/um/Makefile index e55d32e903..1b12feeba3 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \ | |||
17 | 17 | ||
18 | # Have to precede the include because the included Makefiles reference them. | 18 | # Have to precede the include because the included Makefiles reference them. |
19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ | 19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ |
20 | module.h vm-flags.h elf.h | 20 | module.h vm-flags.h elf.h ldt.h |
21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) | 21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) |
22 | 22 | ||
23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes | 23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes |
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index a49ceb199e..6ba8cbbe0d 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h | |||
@@ -16,6 +16,15 @@ extern void stub_clone_handler(void); | |||
16 | #define STUB_MMAP_NR __NR_mmap2 | 16 | #define STUB_MMAP_NR __NR_mmap2 |
17 | #define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) | 17 | #define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) |
18 | 18 | ||
19 | static inline long stub_syscall0(long syscall) | ||
20 | { | ||
21 | long ret; | ||
22 | |||
23 | __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); | ||
24 | |||
25 | return ret; | ||
26 | } | ||
27 | |||
19 | static inline long stub_syscall1(long syscall, long arg1) | 28 | static inline long stub_syscall1(long syscall, long arg1) |
20 | { | 29 | { |
21 | long ret; | 30 | long ret; |
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index 2bd6e7a972..c41689c13d 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h | |||
@@ -6,7 +6,6 @@ | |||
6 | #ifndef __SYSDEP_STUB_H | 6 | #ifndef __SYSDEP_STUB_H |
7 | #define __SYSDEP_STUB_H | 7 | #define __SYSDEP_STUB_H |
8 | 8 | ||
9 | #include <asm/ptrace.h> | ||
10 | #include <asm/unistd.h> | 9 | #include <asm/unistd.h> |
11 | #include <sysdep/ptrace_user.h> | 10 | #include <sysdep/ptrace_user.h> |
12 | 11 | ||
@@ -20,6 +19,17 @@ extern void stub_clone_handler(void); | |||
20 | #define __syscall_clobber "r11","rcx","memory" | 19 | #define __syscall_clobber "r11","rcx","memory" |
21 | #define __syscall "syscall" | 20 | #define __syscall "syscall" |
22 | 21 | ||
22 | static inline long stub_syscall0(long syscall) | ||
23 | { | ||
24 | long ret; | ||
25 | |||
26 | __asm__ volatile (__syscall | ||
27 | : "=a" (ret) | ||
28 | : "0" (syscall) : __syscall_clobber ); | ||
29 | |||
30 | return ret; | ||
31 | } | ||
32 | |||
23 | static inline long stub_syscall2(long syscall, long arg1, long arg2) | 33 | static inline long stub_syscall2(long syscall, long arg1, long arg2) |
24 | { | 34 | { |
25 | long ret; | 35 | long ret; |
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 4dc55f10cd..cb37ce9124 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c | |||
@@ -9,18 +9,24 @@ | |||
9 | #include "stub-data.h" | 9 | #include "stub-data.h" |
10 | #include "uml-config.h" | 10 | #include "uml-config.h" |
11 | #include "sysdep/stub.h" | 11 | #include "sysdep/stub.h" |
12 | #include "kern_constants.h" | ||
12 | 13 | ||
13 | /* This is in a separate file because it needs to be compiled with any | 14 | /* This is in a separate file because it needs to be compiled with any |
14 | * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled | 15 | * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled |
16 | * | ||
17 | * Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize | ||
18 | * on some systems. | ||
15 | */ | 19 | */ |
20 | |||
21 | #define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field) | ||
22 | |||
16 | void __attribute__ ((__section__ (".__syscall_stub"))) | 23 | void __attribute__ ((__section__ (".__syscall_stub"))) |
17 | stub_clone_handler(void) | 24 | stub_clone_handler(void) |
18 | { | 25 | { |
19 | long err; | 26 | long err; |
20 | struct stub_data *from = (struct stub_data *) UML_CONFIG_STUB_DATA; | ||
21 | 27 | ||
22 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, | 28 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, |
23 | UML_CONFIG_STUB_DATA + PAGE_SIZE / 2 - | 29 | UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE / 2 - |
24 | sizeof(void *)); | 30 | sizeof(void *)); |
25 | if(err != 0) | 31 | if(err != 0) |
26 | goto out; | 32 | goto out; |
@@ -30,15 +36,16 @@ stub_clone_handler(void) | |||
30 | goto out; | 36 | goto out; |
31 | 37 | ||
32 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, | 38 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, |
33 | (long) &from->timer, 0); | 39 | (long) &STUB_DATA(timer), 0); |
34 | if(err) | 40 | if(err) |
35 | goto out; | 41 | goto out; |
36 | 42 | ||
37 | err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, PAGE_SIZE, | 43 | err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, |
38 | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, | 44 | UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, |
39 | from->fd, from->offset); | 45 | MAP_FIXED | MAP_SHARED, STUB_DATA(fd), |
46 | STUB_DATA(offset)); | ||
40 | out: | 47 | out: |
41 | /* save current result. Parent: pid; child: retcode of mmap */ | 48 | /* save current result. Parent: pid; child: retcode of mmap */ |
42 | from->err = err; | 49 | STUB_DATA(err) = err; |
43 | trap_myself(); | 50 | trap_myself(); |
44 | } | 51 | } |
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 6dfeb70f69..150059dbee 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
@@ -5,7 +5,7 @@ obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | |||
5 | obj-$(CONFIG_HIGHMEM) += highmem.o | 5 | obj-$(CONFIG_HIGHMEM) += highmem.o |
6 | obj-$(CONFIG_MODULES) += module.o | 6 | obj-$(CONFIG_MODULES) += module.o |
7 | 7 | ||
8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o | 8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o |
9 | 9 | ||
10 | SYMLINKS = bitops.c semaphore.c highmem.c module.c | 10 | SYMLINKS = bitops.c semaphore.c highmem.c module.c |
11 | 11 | ||
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 6360f1c958..17746b4c08 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c | |||
@@ -228,7 +228,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) | |||
228 | size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; | 228 | size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; |
229 | if(size > bytecount) | 229 | if(size > bytecount) |
230 | size = bytecount; | 230 | size = bytecount; |
231 | if(copy_to_user(ptr, ldt->entries, size)) | 231 | if(copy_to_user(ptr, ldt->u.entries, size)) |
232 | err = -EFAULT; | 232 | err = -EFAULT; |
233 | bytecount -= size; | 233 | bytecount -= size; |
234 | ptr += size; | 234 | ptr += size; |
@@ -239,7 +239,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) | |||
239 | size = PAGE_SIZE; | 239 | size = PAGE_SIZE; |
240 | if(size > bytecount) | 240 | if(size > bytecount) |
241 | size = bytecount; | 241 | size = bytecount; |
242 | if(copy_to_user(ptr, ldt->pages[i], size)){ | 242 | if(copy_to_user(ptr, ldt->u.pages[i], size)){ |
243 | err = -EFAULT; | 243 | err = -EFAULT; |
244 | break; | 244 | break; |
245 | } | 245 | } |
@@ -321,10 +321,11 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func) | |||
321 | i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; | 321 | i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; |
322 | i++){ | 322 | i++){ |
323 | if(i == 0) | 323 | if(i == 0) |
324 | memcpy(&entry0, ldt->entries, sizeof(entry0)); | 324 | memcpy(&entry0, ldt->u.entries, |
325 | ldt->pages[i] = (struct ldt_entry *) | 325 | sizeof(entry0)); |
326 | __get_free_page(GFP_KERNEL|__GFP_ZERO); | 326 | ldt->u.pages[i] = (struct ldt_entry *) |
327 | if(!ldt->pages[i]){ | 327 | __get_free_page(GFP_KERNEL|__GFP_ZERO); |
328 | if(!ldt->u.pages[i]){ | ||
328 | err = -ENOMEM; | 329 | err = -ENOMEM; |
329 | /* Undo the change in host */ | 330 | /* Undo the change in host */ |
330 | memset(&ldt_info, 0, sizeof(ldt_info)); | 331 | memset(&ldt_info, 0, sizeof(ldt_info)); |
@@ -332,8 +333,9 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func) | |||
332 | goto out_unlock; | 333 | goto out_unlock; |
333 | } | 334 | } |
334 | if(i == 0) { | 335 | if(i == 0) { |
335 | memcpy(ldt->pages[0], &entry0, sizeof(entry0)); | 336 | memcpy(ldt->u.pages[0], &entry0, |
336 | memcpy(ldt->pages[0]+1, ldt->entries+1, | 337 | sizeof(entry0)); |
338 | memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, | ||
337 | sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); | 339 | sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); |
338 | } | 340 | } |
339 | ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; | 341 | ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; |
@@ -343,9 +345,9 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func) | |||
343 | ldt->entry_count = ldt_info.entry_number + 1; | 345 | ldt->entry_count = ldt_info.entry_number + 1; |
344 | 346 | ||
345 | if(ldt->entry_count <= LDT_DIRECT_ENTRIES) | 347 | if(ldt->entry_count <= LDT_DIRECT_ENTRIES) |
346 | ldt_p = ldt->entries + ldt_info.entry_number; | 348 | ldt_p = ldt->u.entries + ldt_info.entry_number; |
347 | else | 349 | else |
348 | ldt_p = ldt->pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + | 350 | ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + |
349 | ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; | 351 | ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; |
350 | 352 | ||
351 | if(ldt_info.base_addr == 0 && ldt_info.limit == 0 && | 353 | if(ldt_info.base_addr == 0 && ldt_info.limit == 0 && |
@@ -501,8 +503,8 @@ long init_new_ldt(struct mmu_context_skas * new_mm, | |||
501 | */ | 503 | */ |
502 | down(&from_mm->ldt.semaphore); | 504 | down(&from_mm->ldt.semaphore); |
503 | if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){ | 505 | if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){ |
504 | memcpy(new_mm->ldt.entries, from_mm->ldt.entries, | 506 | memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, |
505 | sizeof(new_mm->ldt.entries)); | 507 | sizeof(new_mm->ldt.u.entries)); |
506 | } | 508 | } |
507 | else{ | 509 | else{ |
508 | i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; | 510 | i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; |
@@ -512,9 +514,10 @@ long init_new_ldt(struct mmu_context_skas * new_mm, | |||
512 | err = -ENOMEM; | 514 | err = -ENOMEM; |
513 | break; | 515 | break; |
514 | } | 516 | } |
515 | new_mm->ldt.pages[i] = (struct ldt_entry*)page; | 517 | new_mm->ldt.u.pages[i] = |
516 | memcpy(new_mm->ldt.pages[i], | 518 | (struct ldt_entry *) page; |
517 | from_mm->ldt.pages[i], PAGE_SIZE); | 519 | memcpy(new_mm->ldt.u.pages[i], |
520 | from_mm->ldt.u.pages[i], PAGE_SIZE); | ||
518 | } | 521 | } |
519 | } | 522 | } |
520 | new_mm->ldt.entry_count = from_mm->ldt.entry_count; | 523 | new_mm->ldt.entry_count = from_mm->ldt.entry_count; |
@@ -532,7 +535,7 @@ void free_ldt(struct mmu_context_skas * mm) | |||
532 | if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){ | 535 | if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){ |
533 | i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; | 536 | i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; |
534 | while(i-- > 0){ | 537 | while(i-- > 0){ |
535 | free_page((long )mm->ldt.pages[i]); | 538 | free_page((long )mm->ldt.u.pages[i]); |
536 | } | 539 | } |
537 | } | 540 | } |
538 | mm->ldt.entry_count = 0; | 541 | mm->ldt.entry_count = 0; |
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index 1e88b275ed..a37f672ec9 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
@@ -3,9 +3,11 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <asm/signal.h> | 6 | #include <signal.h> |
7 | #include <sys/select.h> /* The only way I can see to get sigset_t */ | ||
7 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
8 | #include "uml-config.h" | 9 | #include "uml-config.h" |
10 | #include "sysdep/stub.h" | ||
9 | #include "sysdep/sigcontext.h" | 11 | #include "sysdep/sigcontext.h" |
10 | #include "sysdep/faultinfo.h" | 12 | #include "sysdep/faultinfo.h" |
11 | 13 | ||
@@ -13,13 +15,14 @@ void __attribute__ ((__section__ (".__syscall_stub"))) | |||
13 | stub_segv_handler(int sig) | 15 | stub_segv_handler(int sig) |
14 | { | 16 | { |
15 | struct sigcontext *sc = (struct sigcontext *) (&sig + 1); | 17 | struct sigcontext *sc = (struct sigcontext *) (&sig + 1); |
18 | int pid; | ||
16 | 19 | ||
17 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 20 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), |
18 | sc); | 21 | sc); |
19 | 22 | ||
20 | __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); | 23 | pid = stub_syscall0(__NR_getpid); |
21 | __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" | 24 | stub_syscall2(__NR_kill, pid, SIGUSR1); |
22 | "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); | 25 | |
23 | /* Load pointer to sigcontext into esp, since we need to leave | 26 | /* Load pointer to sigcontext into esp, since we need to leave |
24 | * the stack in its original form when we do the sigreturn here, by | 27 | * the stack in its original form when we do the sigreturn here, by |
25 | * hand. | 28 | * hand. |
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index ea977df395..00b2025427 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -12,7 +12,7 @@ lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ | |||
12 | obj-y := ksyms.o | 12 | obj-y := ksyms.o |
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | 13 | obj-$(CONFIG_MODULES) += module.o um_module.o |
14 | 14 | ||
15 | USER_OBJS := ptrace_user.o sigcontext.o | 15 | USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o |
16 | 16 | ||
17 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \ | 17 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \ |
18 | thunk.S module.c | 18 | thunk.S module.c |
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index d1e53bdf2e..a270995331 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c | |||
@@ -3,14 +3,14 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <asm/signal.h> | 6 | #include <stddef.h> |
7 | #include <signal.h> | ||
7 | #include <linux/compiler.h> | 8 | #include <linux/compiler.h> |
8 | #include <asm/unistd.h> | 9 | #include <asm/unistd.h> |
9 | #include <asm/ucontext.h> | ||
10 | #include "uml-config.h" | 10 | #include "uml-config.h" |
11 | #include "sysdep/sigcontext.h" | 11 | #include "sysdep/sigcontext.h" |
12 | #include "sysdep/faultinfo.h" | 12 | #include "sysdep/faultinfo.h" |
13 | #include <stddef.h> | 13 | #include "sysdep/stub.h" |
14 | 14 | ||
15 | /* Copied from sys-x86_64/signal.c - Can't find an equivalent definition | 15 | /* Copied from sys-x86_64/signal.c - Can't find an equivalent definition |
16 | * in the libc headers anywhere. | 16 | * in the libc headers anywhere. |
@@ -31,21 +31,21 @@ void __attribute__ ((__section__ (".__syscall_stub"))) | |||
31 | stub_segv_handler(int sig) | 31 | stub_segv_handler(int sig) |
32 | { | 32 | { |
33 | struct ucontext *uc; | 33 | struct ucontext *uc; |
34 | int pid; | ||
34 | 35 | ||
35 | __asm__("movq %%rdx, %0" : "=g" (uc) :); | 36 | __asm__("movq %%rdx, %0" : "=g" (uc) :); |
36 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), |
37 | &uc->uc_mcontext); | 38 | &uc->uc_mcontext); |
38 | 39 | ||
39 | __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid)); | 40 | pid = stub_syscall0(__NR_getpid); |
40 | __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;" | 41 | stub_syscall2(__NR_kill, pid, SIGUSR1); |
41 | "syscall": : "g" (__NR_kill), "g" (SIGUSR1) : | 42 | |
42 | "%rdi", "%rax", "%rsi"); | ||
43 | /* sys_sigreturn expects that the stack pointer will be 8 bytes into | 43 | /* sys_sigreturn expects that the stack pointer will be 8 bytes into |
44 | * the signal frame. So, we use the ucontext pointer, which we know | 44 | * the signal frame. So, we use the ucontext pointer, which we know |
45 | * already, to get the signal frame pointer, and add 8 to that. | 45 | * already, to get the signal frame pointer, and add 8 to that. |
46 | */ | 46 | */ |
47 | __asm__("movq %0, %%rsp": : | 47 | __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": : |
48 | "g" ((unsigned long) container_of(uc, struct rt_sigframe, | 48 | "g" ((unsigned long) container_of(uc, struct rt_sigframe, |
49 | uc) + 8)); | 49 | uc) + 8), |
50 | __asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn)); | 50 | "g" (__NR_rt_sigreturn)); |
51 | } | 51 | } |