diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-11 11:50:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-11 11:50:01 -0400 |
commit | 37d9869ed928268409b48f52c57449918c0fd307 (patch) | |
tree | 7dd954260d723d1e0716b6432ba07b5c7be7f2ac /arch/s390 | |
parent | 098ef215b1e87cff51f983bae4e4e1358b932ec9 (diff) | |
parent | 89d49841e9e7a90b04b036b7dbe7521b55edbe24 (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: (27 commits)
[S390] Fix checkstack for s390
[S390] fix initialization of stp
[S390] 3215: Remove tasklet.
[S390] console flush on panic / reboot
[S390] introduce dirty bit for kvm live migration
[S390] Add ioctl support for EMC Symmetrix Subsystem Control I/O
[S390] xpram: per device block request queues.
[S390] dasd: fix message flood for unsolicited interrupts
[S390] Move private simple udelay function to arch/s390/lib/delay.c.
[S390] dcssblk: add >2G DCSSs support and stacked contiguous DCSSs support.
[S390] ptrace changes
[S390] s390: use sys_pause for 31bit pause entry point
[S390] qdio enhanced SIGA (iqdio) support.
[S390] cio: fix cio_tpi.
[S390] cio: Correct use of ! and &
[S390] cio: inline assembly cleanup
[S390] bus_id -> dev_set_name() for css and ccw busses
[S390] bus_id ->dev_name() conversions in qdio
[S390] Use s390_root_dev_* in kvm_virtio.
[S390] more bus_id -> dev_name conversions
...
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/Kconfig | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/dasd.h | 13 | ||||
-rw-r--r-- | arch/s390/include/asm/delay.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 45 | ||||
-rw-r--r-- | arch/s390/include/asm/ptrace.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/qdio.h | 8 | ||||
-rw-r--r-- | arch/s390/include/asm/syscall.h | 80 | ||||
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 8 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.h | 1 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 50 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 42 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 61 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 13 | ||||
-rw-r--r-- | arch/s390/kernel/syscalls.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 13 | ||||
-rw-r--r-- | arch/s390/mm/extmem.c | 251 |
19 files changed, 493 insertions, 103 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 8d41908e2513..4c03049e7db9 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -74,6 +74,7 @@ config S390 | |||
74 | select HAVE_KPROBES | 74 | select HAVE_KPROBES |
75 | select HAVE_KRETPROBES | 75 | select HAVE_KRETPROBES |
76 | select HAVE_KVM if 64BIT | 76 | select HAVE_KVM if 64BIT |
77 | select HAVE_ARCH_TRACEHOOK | ||
77 | 78 | ||
78 | source "init/Kconfig" | 79 | source "init/Kconfig" |
79 | 80 | ||
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h index 3f002e13d024..55b2b80cdf6e 100644 --- a/arch/s390/include/asm/dasd.h +++ b/arch/s390/include/asm/dasd.h | |||
@@ -3,6 +3,8 @@ | |||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
6 | * EMC Symmetrix ioctl Copyright EMC Corporation, 2008 | ||
7 | * Author.........: Nigel Hislop <hislop_nigel@emc.com> | ||
6 | * | 8 | * |
7 | * This file is the interface of the DASD device driver, which is exported to user space | 9 | * This file is the interface of the DASD device driver, which is exported to user space |
8 | * any future changes wrt the API will result in a change of the APIVERSION reported | 10 | * any future changes wrt the API will result in a change of the APIVERSION reported |
@@ -202,6 +204,16 @@ typedef struct attrib_data_t { | |||
202 | #define DASD_SEQ_PRESTAGE 0x4 | 204 | #define DASD_SEQ_PRESTAGE 0x4 |
203 | #define DASD_REC_ACCESS 0x5 | 205 | #define DASD_REC_ACCESS 0x5 |
204 | 206 | ||
207 | /* | ||
208 | * Perform EMC Symmetrix I/O | ||
209 | */ | ||
210 | typedef struct dasd_symmio_parms { | ||
211 | unsigned char reserved[8]; /* compat with older releases */ | ||
212 | unsigned long long psf_data; /* char * cast to u64 */ | ||
213 | unsigned long long rssd_result; /* char * cast to u64 */ | ||
214 | int psf_data_len; | ||
215 | int rssd_result_len; | ||
216 | } __attribute__ ((packed)) dasd_symmio_parms_t; | ||
205 | 217 | ||
206 | /******************************************************************************** | 218 | /******************************************************************************** |
207 | * SECTION: Definition of IOCTLs | 219 | * SECTION: Definition of IOCTLs |
@@ -247,6 +259,7 @@ typedef struct attrib_data_t { | |||
247 | /* Set Attributes (cache operations) */ | 259 | /* Set Attributes (cache operations) */ |
248 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) | 260 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) |
249 | 261 | ||
262 | #define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t) | ||
250 | 263 | ||
251 | #endif /* DASD_H */ | 264 | #endif /* DASD_H */ |
252 | 265 | ||
diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h index 78357314c450..a356c958e260 100644 --- a/arch/s390/include/asm/delay.h +++ b/arch/s390/include/asm/delay.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define _S390_DELAY_H | 15 | #define _S390_DELAY_H |
16 | 16 | ||
17 | extern void __udelay(unsigned long usecs); | 17 | extern void __udelay(unsigned long usecs); |
18 | extern void udelay_simple(unsigned long usecs); | ||
18 | extern void __delay(unsigned long loops); | 19 | extern void __delay(unsigned long loops); |
19 | 20 | ||
20 | #define udelay(n) __udelay(n) | 21 | #define udelay(n) __udelay(n) |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0bdb704ae051..1a928f84afd6 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -281,6 +281,9 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
281 | #define RCP_GR_BIT 50 | 281 | #define RCP_GR_BIT 50 |
282 | #define RCP_GC_BIT 49 | 282 | #define RCP_GC_BIT 49 |
283 | 283 | ||
284 | /* User dirty bit for KVM's migration feature */ | ||
285 | #define KVM_UD_BIT 47 | ||
286 | |||
284 | #ifndef __s390x__ | 287 | #ifndef __s390x__ |
285 | 288 | ||
286 | /* Bits in the segment table address-space-control-element */ | 289 | /* Bits in the segment table address-space-control-element */ |
@@ -575,12 +578,16 @@ static inline void ptep_rcp_copy(pte_t *ptep) | |||
575 | unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | 578 | unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); |
576 | 579 | ||
577 | skey = page_get_storage_key(page_to_phys(page)); | 580 | skey = page_get_storage_key(page_to_phys(page)); |
578 | if (skey & _PAGE_CHANGED) | 581 | if (skey & _PAGE_CHANGED) { |
579 | set_bit_simple(RCP_GC_BIT, pgste); | 582 | set_bit_simple(RCP_GC_BIT, pgste); |
583 | set_bit_simple(KVM_UD_BIT, pgste); | ||
584 | } | ||
580 | if (skey & _PAGE_REFERENCED) | 585 | if (skey & _PAGE_REFERENCED) |
581 | set_bit_simple(RCP_GR_BIT, pgste); | 586 | set_bit_simple(RCP_GR_BIT, pgste); |
582 | if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) | 587 | if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) { |
583 | SetPageDirty(page); | 588 | SetPageDirty(page); |
589 | set_bit_simple(KVM_UD_BIT, pgste); | ||
590 | } | ||
584 | if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) | 591 | if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) |
585 | SetPageReferenced(page); | 592 | SetPageReferenced(page); |
586 | #endif | 593 | #endif |
@@ -744,6 +751,40 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
744 | return pte; | 751 | return pte; |
745 | } | 752 | } |
746 | 753 | ||
754 | #ifdef CONFIG_PGSTE | ||
755 | /* | ||
756 | * Get (and clear) the user dirty bit for a PTE. | ||
757 | */ | ||
758 | static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, | ||
759 | pte_t *ptep) | ||
760 | { | ||
761 | int dirty; | ||
762 | unsigned long *pgste; | ||
763 | struct page *page; | ||
764 | unsigned int skey; | ||
765 | |||
766 | if (!mm->context.pgstes) | ||
767 | return -EINVAL; | ||
768 | rcp_lock(ptep); | ||
769 | pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | ||
770 | page = virt_to_page(pte_val(*ptep)); | ||
771 | skey = page_get_storage_key(page_to_phys(page)); | ||
772 | if (skey & _PAGE_CHANGED) { | ||
773 | set_bit_simple(RCP_GC_BIT, pgste); | ||
774 | set_bit_simple(KVM_UD_BIT, pgste); | ||
775 | } | ||
776 | if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) { | ||
777 | SetPageDirty(page); | ||
778 | set_bit_simple(KVM_UD_BIT, pgste); | ||
779 | } | ||
780 | dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); | ||
781 | if (skey & _PAGE_CHANGED) | ||
782 | page_clear_dirty(page); | ||
783 | rcp_unlock(ptep); | ||
784 | return dirty; | ||
785 | } | ||
786 | #endif | ||
787 | |||
747 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 788 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
748 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, | 789 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, |
749 | unsigned long addr, pte_t *ptep) | 790 | unsigned long addr, pte_t *ptep) |
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index af2c9ac28a07..a7226f8143fb 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -490,6 +490,7 @@ extern void user_disable_single_step(struct task_struct *); | |||
490 | 490 | ||
491 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | 491 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) |
492 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | 492 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) |
493 | #define user_stack_pointer(regs)((regs)->gprs[15]) | ||
493 | #define regs_return_value(regs)((regs)->gprs[2]) | 494 | #define regs_return_value(regs)((regs)->gprs[2]) |
494 | #define profile_pc(regs) instruction_pointer(regs) | 495 | #define profile_pc(regs) instruction_pointer(regs) |
495 | extern void show_regs(struct pt_regs * regs); | 496 | extern void show_regs(struct pt_regs * regs); |
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 6813772171f2..4734c3f05354 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h | |||
@@ -299,7 +299,13 @@ struct qdio_ssqd_desc { | |||
299 | u8 mbccnt; | 299 | u8 mbccnt; |
300 | u16 qdioac2; | 300 | u16 qdioac2; |
301 | u64 sch_token; | 301 | u64 sch_token; |
302 | u64:64; | 302 | u8 mro; |
303 | u8 mri; | ||
304 | u8:8; | ||
305 | u8 sbalic; | ||
306 | u16:16; | ||
307 | u8:8; | ||
308 | u8 mmwc; | ||
303 | } __attribute__ ((packed)); | 309 | } __attribute__ ((packed)); |
304 | 310 | ||
305 | /* params are: ccw_device, qdio_error, queue_number, | 311 | /* params are: ccw_device, qdio_error, queue_number, |
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h new file mode 100644 index 000000000000..6e623971fbb9 --- /dev/null +++ b/arch/s390/include/asm/syscall.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Access to user system call parameters and results | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License (version 2 only) | ||
9 | * as published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_SYSCALL_H | ||
13 | #define _ASM_SYSCALL_H 1 | ||
14 | |||
15 | #include <asm/ptrace.h> | ||
16 | |||
17 | static inline long syscall_get_nr(struct task_struct *task, | ||
18 | struct pt_regs *regs) | ||
19 | { | ||
20 | if (regs->trap != __LC_SVC_OLD_PSW) | ||
21 | return -1; | ||
22 | return regs->gprs[2]; | ||
23 | } | ||
24 | |||
25 | static inline void syscall_rollback(struct task_struct *task, | ||
26 | struct pt_regs *regs) | ||
27 | { | ||
28 | regs->gprs[2] = regs->orig_gpr2; | ||
29 | } | ||
30 | |||
31 | static inline long syscall_get_error(struct task_struct *task, | ||
32 | struct pt_regs *regs) | ||
33 | { | ||
34 | return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0; | ||
35 | } | ||
36 | |||
37 | static inline long syscall_get_return_value(struct task_struct *task, | ||
38 | struct pt_regs *regs) | ||
39 | { | ||
40 | return regs->gprs[2]; | ||
41 | } | ||
42 | |||
43 | static inline void syscall_set_return_value(struct task_struct *task, | ||
44 | struct pt_regs *regs, | ||
45 | int error, long val) | ||
46 | { | ||
47 | regs->gprs[2] = error ? -error : val; | ||
48 | } | ||
49 | |||
50 | static inline void syscall_get_arguments(struct task_struct *task, | ||
51 | struct pt_regs *regs, | ||
52 | unsigned int i, unsigned int n, | ||
53 | unsigned long *args) | ||
54 | { | ||
55 | BUG_ON(i + n > 6); | ||
56 | #ifdef CONFIG_COMPAT | ||
57 | if (test_tsk_thread_flag(task, TIF_31BIT)) { | ||
58 | if (i + n == 6) | ||
59 | args[--n] = (u32) regs->args[0]; | ||
60 | while (n-- > 0) | ||
61 | args[n] = (u32) regs->gprs[2 + i + n]; | ||
62 | } | ||
63 | #endif | ||
64 | if (i + n == 6) | ||
65 | args[--n] = regs->args[0]; | ||
66 | memcpy(args, ®s->gprs[2 + i], n * sizeof(args[0])); | ||
67 | } | ||
68 | |||
69 | static inline void syscall_set_arguments(struct task_struct *task, | ||
70 | struct pt_regs *regs, | ||
71 | unsigned int i, unsigned int n, | ||
72 | const unsigned long *args) | ||
73 | { | ||
74 | BUG_ON(i + n > 6); | ||
75 | if (i + n == 6) | ||
76 | regs->args[0] = args[--n]; | ||
77 | memcpy(®s->gprs[2 + i], args, n * sizeof(args[0])); | ||
78 | } | ||
79 | |||
80 | #endif /* _ASM_SYSCALL_H */ | ||
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 91a8f93ad355..ea40a9d690fc 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -86,6 +86,7 @@ static inline struct thread_info *current_thread_info(void) | |||
86 | * thread information flags bit numbers | 86 | * thread information flags bit numbers |
87 | */ | 87 | */ |
88 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 88 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
89 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ | ||
89 | #define TIF_SIGPENDING 2 /* signal pending */ | 90 | #define TIF_SIGPENDING 2 /* signal pending */ |
90 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 91 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
91 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | 92 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ |
@@ -100,6 +101,7 @@ static inline struct thread_info *current_thread_info(void) | |||
100 | #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ | 101 | #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ |
101 | 102 | ||
102 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 103 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
104 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
103 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 105 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
104 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 106 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
105 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 107 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index d7f22226fc4e..98e246dc0233 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -608,14 +608,6 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct time | |||
608 | return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); | 608 | return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); |
609 | } | 609 | } |
610 | 610 | ||
611 | /* These are here just in case some old sparc32 binary calls it. */ | ||
612 | asmlinkage long sys32_pause(void) | ||
613 | { | ||
614 | current->state = TASK_INTERRUPTIBLE; | ||
615 | schedule(); | ||
616 | return -ERESTARTNOHAND; | ||
617 | } | ||
618 | |||
619 | asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, | 611 | asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, |
620 | size_t count, u32 poshi, u32 poslo) | 612 | size_t count, u32 poshi, u32 poslo) |
621 | { | 613 | { |
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 20723a062017..05f8516366ab 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h | |||
@@ -206,7 +206,6 @@ long sys32_gettimeofday(struct compat_timeval __user *tv, | |||
206 | struct timezone __user *tz); | 206 | struct timezone __user *tz); |
207 | long sys32_settimeofday(struct compat_timeval __user *tv, | 207 | long sys32_settimeofday(struct compat_timeval __user *tv, |
208 | struct timezone __user *tz); | 208 | struct timezone __user *tz); |
209 | long sys32_pause(void); | ||
210 | long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, | 209 | long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, |
211 | u32 poshi, u32 poslo); | 210 | u32 poshi, u32 poslo); |
212 | long sys32_pwrite64(unsigned int fd, const char __user *ubuf, | 211 | long sys32_pwrite64(unsigned int fd, const char __user *ubuf, |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 328a20e880b5..ee51ca9e23b5 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -128,8 +128,6 @@ sys32_alarm_wrapper: | |||
128 | llgfr %r2,%r2 # unsigned int | 128 | llgfr %r2,%r2 # unsigned int |
129 | jg sys_alarm # branch to system call | 129 | jg sys_alarm # branch to system call |
130 | 130 | ||
131 | #sys32_pause_wrapper # void | ||
132 | |||
133 | .globl compat_sys_utime_wrapper | 131 | .globl compat_sys_utime_wrapper |
134 | compat_sys_utime_wrapper: | 132 | compat_sys_utime_wrapper: |
135 | llgtr %r2,%r2 # char * | 133 | llgtr %r2,%r2 # char * |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 708cf9cf9a35..ed500ef799b7 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | |||
49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP |
50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
51 | 51 | ||
52 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 52 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
53 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 53 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
55 | _TIF_MCCK_PENDING) | 55 | _TIF_MCCK_PENDING) |
56 | 56 | ||
57 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 57 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
@@ -318,6 +318,8 @@ sysc_work: | |||
318 | bo BASED(sysc_reschedule) | 318 | bo BASED(sysc_reschedule) |
319 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 319 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
320 | bnz BASED(sysc_sigpending) | 320 | bnz BASED(sysc_sigpending) |
321 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | ||
322 | bnz BASED(sysc_notify_resume) | ||
321 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 323 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC |
322 | bo BASED(sysc_restart) | 324 | bo BASED(sysc_restart) |
323 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 325 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
@@ -356,6 +358,16 @@ sysc_sigpending: | |||
356 | b BASED(sysc_work_loop) | 358 | b BASED(sysc_work_loop) |
357 | 359 | ||
358 | # | 360 | # |
361 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | ||
362 | # | ||
363 | sysc_notify_resume: | ||
364 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
365 | l %r1,BASED(.Ldo_notify_resume) | ||
366 | la %r14,BASED(sysc_work_loop) | ||
367 | br %r1 # call do_notify_resume | ||
368 | |||
369 | |||
370 | # | ||
359 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 371 | # _TIF_RESTART_SVC is set, set up registers and restart svc |
360 | # | 372 | # |
361 | sysc_restart: | 373 | sysc_restart: |
@@ -378,20 +390,21 @@ sysc_singlestep: | |||
378 | br %r1 # branch to do_single_step | 390 | br %r1 # branch to do_single_step |
379 | 391 | ||
380 | # | 392 | # |
381 | # call trace before and after sys_call | 393 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before |
394 | # and after the system call | ||
382 | # | 395 | # |
383 | sysc_tracesys: | 396 | sysc_tracesys: |
384 | l %r1,BASED(.Ltrace) | 397 | l %r1,BASED(.Ltrace_entry) |
385 | la %r2,SP_PTREGS(%r15) # load pt_regs | 398 | la %r2,SP_PTREGS(%r15) # load pt_regs |
386 | la %r3,0 | 399 | la %r3,0 |
387 | srl %r7,2 | 400 | srl %r7,2 |
388 | st %r7,SP_R2(%r15) | 401 | st %r7,SP_R2(%r15) |
389 | basr %r14,%r1 | 402 | basr %r14,%r1 |
390 | clc SP_R2(4,%r15),BASED(.Lnr_syscalls) | 403 | cl %r2,BASED(.Lnr_syscalls) |
391 | bnl BASED(sysc_tracenogo) | 404 | bnl BASED(sysc_tracenogo) |
392 | l %r8,BASED(.Lsysc_table) | 405 | l %r8,BASED(.Lsysc_table) |
393 | l %r7,SP_R2(%r15) # strace might have changed the | 406 | lr %r7,%r2 |
394 | sll %r7,2 # system call | 407 | sll %r7,2 # *4 |
395 | l %r8,0(%r7,%r8) | 408 | l %r8,0(%r7,%r8) |
396 | sysc_tracego: | 409 | sysc_tracego: |
397 | lm %r3,%r6,SP_R3(%r15) | 410 | lm %r3,%r6,SP_R3(%r15) |
@@ -401,9 +414,8 @@ sysc_tracego: | |||
401 | sysc_tracenogo: | 414 | sysc_tracenogo: |
402 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) | 415 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) |
403 | bz BASED(sysc_return) | 416 | bz BASED(sysc_return) |
404 | l %r1,BASED(.Ltrace) | 417 | l %r1,BASED(.Ltrace_exit) |
405 | la %r2,SP_PTREGS(%r15) # load pt_regs | 418 | la %r2,SP_PTREGS(%r15) # load pt_regs |
406 | la %r3,1 | ||
407 | la %r14,BASED(sysc_return) | 419 | la %r14,BASED(sysc_return) |
408 | br %r1 | 420 | br %r1 |
409 | 421 | ||
@@ -666,6 +678,8 @@ io_work_loop: | |||
666 | bo BASED(io_reschedule) | 678 | bo BASED(io_reschedule) |
667 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 679 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
668 | bnz BASED(io_sigpending) | 680 | bnz BASED(io_sigpending) |
681 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | ||
682 | bnz BASED(io_notify_resume) | ||
669 | b BASED(io_restore) | 683 | b BASED(io_restore) |
670 | io_work_done: | 684 | io_work_done: |
671 | 685 | ||
@@ -704,6 +718,19 @@ io_sigpending: | |||
704 | TRACE_IRQS_OFF | 718 | TRACE_IRQS_OFF |
705 | b BASED(io_work_loop) | 719 | b BASED(io_work_loop) |
706 | 720 | ||
721 | # | ||
722 | # _TIF_SIGPENDING is set, call do_signal | ||
723 | # | ||
724 | io_notify_resume: | ||
725 | TRACE_IRQS_ON | ||
726 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | ||
727 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
728 | l %r1,BASED(.Ldo_notify_resume) | ||
729 | basr %r14,%r1 # call do_signal | ||
730 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | ||
731 | TRACE_IRQS_OFF | ||
732 | b BASED(io_work_loop) | ||
733 | |||
707 | /* | 734 | /* |
708 | * External interrupt handler routine | 735 | * External interrupt handler routine |
709 | */ | 736 | */ |
@@ -1070,6 +1097,8 @@ cleanup_io_leave_insn: | |||
1070 | .Ldo_IRQ: .long do_IRQ | 1097 | .Ldo_IRQ: .long do_IRQ |
1071 | .Ldo_extint: .long do_extint | 1098 | .Ldo_extint: .long do_extint |
1072 | .Ldo_signal: .long do_signal | 1099 | .Ldo_signal: .long do_signal |
1100 | .Ldo_notify_resume: | ||
1101 | .long do_notify_resume | ||
1073 | .Lhandle_per: .long do_single_step | 1102 | .Lhandle_per: .long do_single_step |
1074 | .Ldo_execve: .long do_execve | 1103 | .Ldo_execve: .long do_execve |
1075 | .Lexecve_tail: .long execve_tail | 1104 | .Lexecve_tail: .long execve_tail |
@@ -1079,7 +1108,8 @@ cleanup_io_leave_insn: | |||
1079 | .Lpreempt_schedule_irq: | 1108 | .Lpreempt_schedule_irq: |
1080 | .long preempt_schedule_irq | 1109 | .long preempt_schedule_irq |
1081 | #endif | 1110 | #endif |
1082 | .Ltrace: .long syscall_trace | 1111 | .Ltrace_entry: .long do_syscall_trace_enter |
1112 | .Ltrace_exit: .long do_syscall_trace_exit | ||
1083 | .Lschedtail: .long schedule_tail | 1113 | .Lschedtail: .long schedule_tail |
1084 | .Lsysc_table: .long sys_call_table | 1114 | .Lsysc_table: .long sys_call_table |
1085 | #ifdef CONFIG_TRACE_IRQFLAGS | 1115 | #ifdef CONFIG_TRACE_IRQFLAGS |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index fee10177dbfc..d7ce150453f2 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -52,9 +52,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | |||
52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
53 | STACK_SIZE = 1 << STACK_SHIFT | 53 | STACK_SIZE = 1 << STACK_SHIFT |
54 | 54 | ||
55 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 55 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
56 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 56 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
58 | _TIF_MCCK_PENDING) | 58 | _TIF_MCCK_PENDING) |
59 | 59 | ||
60 | #define BASED(name) name-system_call(%r13) | 60 | #define BASED(name) name-system_call(%r13) |
@@ -310,6 +310,8 @@ sysc_work: | |||
310 | jo sysc_reschedule | 310 | jo sysc_reschedule |
311 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 311 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
312 | jnz sysc_sigpending | 312 | jnz sysc_sigpending |
313 | tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME | ||
314 | jnz sysc_notify_resume | ||
313 | tm __TI_flags+7(%r9),_TIF_RESTART_SVC | 315 | tm __TI_flags+7(%r9),_TIF_RESTART_SVC |
314 | jo sysc_restart | 316 | jo sysc_restart |
315 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP | 317 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP |
@@ -345,6 +347,14 @@ sysc_sigpending: | |||
345 | j sysc_work_loop | 347 | j sysc_work_loop |
346 | 348 | ||
347 | # | 349 | # |
350 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | ||
351 | # | ||
352 | sysc_notify_resume: | ||
353 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
354 | larl %r14,sysc_work_loop | ||
355 | jg do_notify_resume # call do_notify_resume | ||
356 | |||
357 | # | ||
348 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 358 | # _TIF_RESTART_SVC is set, set up registers and restart svc |
349 | # | 359 | # |
350 | sysc_restart: | 360 | sysc_restart: |
@@ -367,20 +377,19 @@ sysc_singlestep: | |||
367 | jg do_single_step # branch to do_sigtrap | 377 | jg do_single_step # branch to do_sigtrap |
368 | 378 | ||
369 | # | 379 | # |
370 | # call syscall_trace before and after system call | 380 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before |
371 | # special linkage: %r12 contains the return address for trace_svc | 381 | # and after the system call |
372 | # | 382 | # |
373 | sysc_tracesys: | 383 | sysc_tracesys: |
374 | la %r2,SP_PTREGS(%r15) # load pt_regs | 384 | la %r2,SP_PTREGS(%r15) # load pt_regs |
375 | la %r3,0 | 385 | la %r3,0 |
376 | srl %r7,2 | 386 | srl %r7,2 |
377 | stg %r7,SP_R2(%r15) | 387 | stg %r7,SP_R2(%r15) |
378 | brasl %r14,syscall_trace | 388 | brasl %r14,do_syscall_trace_enter |
379 | lghi %r0,NR_syscalls | 389 | lghi %r0,NR_syscalls |
380 | clg %r0,SP_R2(%r15) | 390 | clgr %r0,%r2 |
381 | jnh sysc_tracenogo | 391 | jnh sysc_tracenogo |
382 | lg %r7,SP_R2(%r15) # strace might have changed the | 392 | slag %r7,%r2,2 # *4 |
383 | sll %r7,2 # system call | ||
384 | lgf %r8,0(%r7,%r10) | 393 | lgf %r8,0(%r7,%r10) |
385 | sysc_tracego: | 394 | sysc_tracego: |
386 | lmg %r3,%r6,SP_R3(%r15) | 395 | lmg %r3,%r6,SP_R3(%r15) |
@@ -391,9 +400,8 @@ sysc_tracenogo: | |||
391 | tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) | 400 | tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) |
392 | jz sysc_return | 401 | jz sysc_return |
393 | la %r2,SP_PTREGS(%r15) # load pt_regs | 402 | la %r2,SP_PTREGS(%r15) # load pt_regs |
394 | la %r3,1 | ||
395 | larl %r14,sysc_return # return point is sysc_return | 403 | larl %r14,sysc_return # return point is sysc_return |
396 | jg syscall_trace | 404 | jg do_syscall_trace_exit |
397 | 405 | ||
398 | # | 406 | # |
399 | # a new process exits the kernel with ret_from_fork | 407 | # a new process exits the kernel with ret_from_fork |
@@ -672,6 +680,8 @@ io_work_loop: | |||
672 | jo io_reschedule | 680 | jo io_reschedule |
673 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 681 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
674 | jnz io_sigpending | 682 | jnz io_sigpending |
683 | tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME | ||
684 | jnz io_notify_resume | ||
675 | j io_restore | 685 | j io_restore |
676 | io_work_done: | 686 | io_work_done: |
677 | 687 | ||
@@ -712,6 +722,18 @@ io_sigpending: | |||
712 | TRACE_IRQS_OFF | 722 | TRACE_IRQS_OFF |
713 | j io_work_loop | 723 | j io_work_loop |
714 | 724 | ||
725 | # | ||
726 | # _TIF_NOTIFY_RESUME or is set, call do_notify_resume | ||
727 | # | ||
728 | io_notify_resume: | ||
729 | TRACE_IRQS_ON | ||
730 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | ||
731 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
732 | brasl %r14,do_notify_resume # call do_notify_resume | ||
733 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | ||
734 | TRACE_IRQS_OFF | ||
735 | j io_work_loop | ||
736 | |||
715 | /* | 737 | /* |
716 | * External interrupt handler routine | 738 | * External interrupt handler routine |
717 | */ | 739 | */ |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c8b08289eb87..1f31be1ecc4b 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/signal.h> | 35 | #include <linux/signal.h> |
36 | #include <linux/elf.h> | 36 | #include <linux/elf.h> |
37 | #include <linux/regset.h> | 37 | #include <linux/regset.h> |
38 | #include <linux/tracehook.h> | ||
38 | 39 | ||
39 | #include <asm/segment.h> | 40 | #include <asm/segment.h> |
40 | #include <asm/page.h> | 41 | #include <asm/page.h> |
@@ -639,40 +640,44 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
639 | } | 640 | } |
640 | #endif | 641 | #endif |
641 | 642 | ||
642 | asmlinkage void | 643 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
643 | syscall_trace(struct pt_regs *regs, int entryexit) | ||
644 | { | 644 | { |
645 | if (unlikely(current->audit_context) && entryexit) | 645 | long ret; |
646 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); | ||
647 | |||
648 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | ||
649 | goto out; | ||
650 | if (!(current->ptrace & PT_PTRACED)) | ||
651 | goto out; | ||
652 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | ||
653 | ? 0x80 : 0)); | ||
654 | 646 | ||
655 | /* | 647 | /* |
656 | * If the debuffer has set an invalid system call number, | 648 | * The sysc_tracesys code in entry.S stored the system |
657 | * we prepare to skip the system call restart handling. | 649 | * call number to gprs[2]. |
658 | */ | 650 | */ |
659 | if (!entryexit && regs->gprs[2] >= NR_syscalls) | 651 | ret = regs->gprs[2]; |
652 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | ||
653 | (tracehook_report_syscall_entry(regs) || | ||
654 | regs->gprs[2] >= NR_syscalls)) { | ||
655 | /* | ||
656 | * Tracing decided this syscall should not happen or the | ||
657 | * debugger stored an invalid system call number. Skip | ||
658 | * the system call and the system call restart handling. | ||
659 | */ | ||
660 | regs->trap = -1; | 660 | regs->trap = -1; |
661 | 661 | ret = -1; | |
662 | /* | ||
663 | * this isn't the same as continuing with a signal, but it will do | ||
664 | * for normal use. strace only continues with a signal if the | ||
665 | * stopping signal is not SIGTRAP. -brl | ||
666 | */ | ||
667 | if (current->exit_code) { | ||
668 | send_sig(current->exit_code, current, 1); | ||
669 | current->exit_code = 0; | ||
670 | } | 662 | } |
671 | out: | 663 | |
672 | if (unlikely(current->audit_context) && !entryexit) | 664 | if (unlikely(current->audit_context)) |
673 | audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, | 665 | audit_syscall_entry(test_thread_flag(TIF_31BIT) ? |
674 | regs->gprs[2], regs->orig_gpr2, regs->gprs[3], | 666 | AUDIT_ARCH_S390 : AUDIT_ARCH_S390X, |
675 | regs->gprs[4], regs->gprs[5]); | 667 | regs->gprs[2], regs->orig_gpr2, |
668 | regs->gprs[3], regs->gprs[4], | ||
669 | regs->gprs[5]); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) | ||
674 | { | ||
675 | if (unlikely(current->audit_context)) | ||
676 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), | ||
677 | regs->gprs[2]); | ||
678 | |||
679 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | ||
680 | tracehook_report_syscall_exit(regs, 0); | ||
676 | } | 681 | } |
677 | 682 | ||
678 | /* | 683 | /* |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index b97682040215..4f7fc3059a8e 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/tty.h> | 24 | #include <linux/tty.h> |
25 | #include <linux/personality.h> | 25 | #include <linux/personality.h> |
26 | #include <linux/binfmts.h> | 26 | #include <linux/binfmts.h> |
27 | #include <linux/tracehook.h> | ||
27 | #include <asm/ucontext.h> | 28 | #include <asm/ucontext.h> |
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/lowcore.h> | 30 | #include <asm/lowcore.h> |
@@ -507,6 +508,12 @@ void do_signal(struct pt_regs *regs) | |||
507 | */ | 508 | */ |
508 | if (current->thread.per_info.single_step) | 509 | if (current->thread.per_info.single_step) |
509 | set_thread_flag(TIF_SINGLE_STEP); | 510 | set_thread_flag(TIF_SINGLE_STEP); |
511 | |||
512 | /* | ||
513 | * Let tracing know that we've done the handler setup. | ||
514 | */ | ||
515 | tracehook_signal_handler(signr, &info, &ka, regs, | ||
516 | test_thread_flag(TIF_SINGLE_STEP)); | ||
510 | } | 517 | } |
511 | return; | 518 | return; |
512 | } | 519 | } |
@@ -526,3 +533,9 @@ void do_signal(struct pt_regs *regs) | |||
526 | set_thread_flag(TIF_RESTART_SVC); | 533 | set_thread_flag(TIF_RESTART_SVC); |
527 | } | 534 | } |
528 | } | 535 | } |
536 | |||
537 | void do_notify_resume(struct pt_regs *regs) | ||
538 | { | ||
539 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
540 | tracehook_notify_resume(regs); | ||
541 | } | ||
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index c66d35e55142..3ae303914b42 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -37,7 +37,7 @@ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall * | |||
37 | SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) | 37 | SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) |
38 | SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper) | 38 | SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper) |
39 | NI_SYSCALL /* old fstat syscall */ | 39 | NI_SYSCALL /* old fstat syscall */ |
40 | SYSCALL(sys_pause,sys_pause,sys32_pause) | 40 | SYSCALL(sys_pause,sys_pause,sys_pause) |
41 | SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */ | 41 | SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */ |
42 | NI_SYSCALL /* old stty syscall */ | 42 | NI_SYSCALL /* old stty syscall */ |
43 | NI_SYSCALL /* old gtty syscall */ | 43 | NI_SYSCALL /* old gtty syscall */ |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 06acb1a18bbc..b94e9e3b694a 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -1356,7 +1356,7 @@ static void __init stp_reset(void) | |||
1356 | 1356 | ||
1357 | stp_page = alloc_bootmem_pages(PAGE_SIZE); | 1357 | stp_page = alloc_bootmem_pages(PAGE_SIZE); |
1358 | rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); | 1358 | rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); |
1359 | if (rc == 1) | 1359 | if (rc == 0) |
1360 | set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags); | 1360 | set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags); |
1361 | else if (stp_online) { | 1361 | else if (stp_online) { |
1362 | printk(KERN_WARNING "Running on non STP capable machine.\n"); | 1362 | printk(KERN_WARNING "Running on non STP capable machine.\n"); |
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 0953cee05efc..6ccb9fab055a 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -92,3 +92,16 @@ out: | |||
92 | local_irq_restore(flags); | 92 | local_irq_restore(flags); |
93 | preempt_enable(); | 93 | preempt_enable(); |
94 | } | 94 | } |
95 | |||
96 | /* | ||
97 | * Simple udelay variant. To be used on startup and reboot | ||
98 | * when the interrupt handler isn't working. | ||
99 | */ | ||
100 | void udelay_simple(unsigned long usecs) | ||
101 | { | ||
102 | u64 end; | ||
103 | |||
104 | end = get_clock() + ((u64) usecs << 12); | ||
105 | while (get_clock() < end) | ||
106 | cpu_relax(); | ||
107 | } | ||
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index f231f5ec74b6..580fc64cc735 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -43,20 +43,40 @@ | |||
43 | #define DCSS_FINDSEG 0x0c | 43 | #define DCSS_FINDSEG 0x0c |
44 | #define DCSS_LOADNOLY 0x10 | 44 | #define DCSS_LOADNOLY 0x10 |
45 | #define DCSS_SEGEXT 0x18 | 45 | #define DCSS_SEGEXT 0x18 |
46 | #define DCSS_LOADSHRX 0x20 | ||
47 | #define DCSS_LOADNSRX 0x24 | ||
48 | #define DCSS_FINDSEGX 0x2c | ||
49 | #define DCSS_SEGEXTX 0x38 | ||
46 | #define DCSS_FINDSEGA 0x0c | 50 | #define DCSS_FINDSEGA 0x0c |
47 | 51 | ||
48 | struct qrange { | 52 | struct qrange { |
49 | unsigned int start; // 3byte start address, 1 byte type | 53 | unsigned long start; /* last byte type */ |
50 | unsigned int end; // 3byte end address, 1 byte reserved | 54 | unsigned long end; /* last byte reserved */ |
51 | }; | 55 | }; |
52 | 56 | ||
53 | struct qout64 { | 57 | struct qout64 { |
58 | unsigned long segstart; | ||
59 | unsigned long segend; | ||
60 | int segcnt; | ||
61 | int segrcnt; | ||
62 | struct qrange range[6]; | ||
63 | }; | ||
64 | |||
65 | #ifdef CONFIG_64BIT | ||
66 | struct qrange_old { | ||
67 | unsigned int start; /* last byte type */ | ||
68 | unsigned int end; /* last byte reserved */ | ||
69 | }; | ||
70 | |||
71 | /* output area format for the Diag x'64' old subcode x'18' */ | ||
72 | struct qout64_old { | ||
54 | int segstart; | 73 | int segstart; |
55 | int segend; | 74 | int segend; |
56 | int segcnt; | 75 | int segcnt; |
57 | int segrcnt; | 76 | int segrcnt; |
58 | struct qrange range[6]; | 77 | struct qrange_old range[6]; |
59 | }; | 78 | }; |
79 | #endif | ||
60 | 80 | ||
61 | struct qin64 { | 81 | struct qin64 { |
62 | char qopcode; | 82 | char qopcode; |
@@ -86,6 +106,55 @@ static DEFINE_MUTEX(dcss_lock); | |||
86 | static LIST_HEAD(dcss_list); | 106 | static LIST_HEAD(dcss_list); |
87 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", | 107 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", |
88 | "EW/EN-MIXED" }; | 108 | "EW/EN-MIXED" }; |
109 | static int loadshr_scode, loadnsr_scode, findseg_scode; | ||
110 | static int segext_scode, purgeseg_scode; | ||
111 | static int scode_set; | ||
112 | |||
113 | /* set correct Diag x'64' subcodes. */ | ||
114 | static int | ||
115 | dcss_set_subcodes(void) | ||
116 | { | ||
117 | #ifdef CONFIG_64BIT | ||
118 | char *name = kmalloc(8 * sizeof(char), GFP_DMA); | ||
119 | unsigned long rx, ry; | ||
120 | int rc; | ||
121 | |||
122 | if (name == NULL) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | rx = (unsigned long) name; | ||
126 | ry = DCSS_FINDSEGX; | ||
127 | |||
128 | strcpy(name, "dummy"); | ||
129 | asm volatile( | ||
130 | " diag %0,%1,0x64\n" | ||
131 | "0: ipm %2\n" | ||
132 | " srl %2,28\n" | ||
133 | " j 2f\n" | ||
134 | "1: la %2,3\n" | ||
135 | "2:\n" | ||
136 | EX_TABLE(0b, 1b) | ||
137 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | ||
138 | |||
139 | kfree(name); | ||
140 | /* Diag x'64' new subcodes are supported, set to new subcodes */ | ||
141 | if (rc != 3) { | ||
142 | loadshr_scode = DCSS_LOADSHRX; | ||
143 | loadnsr_scode = DCSS_LOADNSRX; | ||
144 | purgeseg_scode = DCSS_PURGESEG; | ||
145 | findseg_scode = DCSS_FINDSEGX; | ||
146 | segext_scode = DCSS_SEGEXTX; | ||
147 | return 0; | ||
148 | } | ||
149 | #endif | ||
150 | /* Diag x'64' new subcodes are not supported, set to old subcodes */ | ||
151 | loadshr_scode = DCSS_LOADNOLY; | ||
152 | loadnsr_scode = DCSS_LOADNSR; | ||
153 | purgeseg_scode = DCSS_PURGESEG; | ||
154 | findseg_scode = DCSS_FINDSEG; | ||
155 | segext_scode = DCSS_SEGEXT; | ||
156 | return 0; | ||
157 | } | ||
89 | 158 | ||
90 | /* | 159 | /* |
91 | * Create the 8 bytes, ebcdic VM segment name from | 160 | * Create the 8 bytes, ebcdic VM segment name from |
@@ -135,25 +204,45 @@ segment_by_name (char *name) | |||
135 | * Perform a function on a dcss segment. | 204 | * Perform a function on a dcss segment. |
136 | */ | 205 | */ |
137 | static inline int | 206 | static inline int |
138 | dcss_diag (__u8 func, void *parameter, | 207 | dcss_diag(int *func, void *parameter, |
139 | unsigned long *ret1, unsigned long *ret2) | 208 | unsigned long *ret1, unsigned long *ret2) |
140 | { | 209 | { |
141 | unsigned long rx, ry; | 210 | unsigned long rx, ry; |
142 | int rc; | 211 | int rc; |
143 | 212 | ||
213 | if (scode_set == 0) { | ||
214 | rc = dcss_set_subcodes(); | ||
215 | if (rc < 0) | ||
216 | return rc; | ||
217 | scode_set = 1; | ||
218 | } | ||
144 | rx = (unsigned long) parameter; | 219 | rx = (unsigned long) parameter; |
145 | ry = (unsigned long) func; | 220 | ry = (unsigned long) *func; |
146 | asm volatile( | 221 | |
147 | #ifdef CONFIG_64BIT | 222 | #ifdef CONFIG_64BIT |
148 | " sam31\n" | 223 | /* 64-bit Diag x'64' new subcode, keep in 64-bit addressing mode */ |
149 | " diag %0,%1,0x64\n" | 224 | if (*func > DCSS_SEGEXT) |
150 | " sam64\n" | 225 | asm volatile( |
226 | " diag %0,%1,0x64\n" | ||
227 | " ipm %2\n" | ||
228 | " srl %2,28\n" | ||
229 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | ||
230 | /* 31-bit Diag x'64' old subcode, switch to 31-bit addressing mode */ | ||
231 | else | ||
232 | asm volatile( | ||
233 | " sam31\n" | ||
234 | " diag %0,%1,0x64\n" | ||
235 | " sam64\n" | ||
236 | " ipm %2\n" | ||
237 | " srl %2,28\n" | ||
238 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | ||
151 | #else | 239 | #else |
240 | asm volatile( | ||
152 | " diag %0,%1,0x64\n" | 241 | " diag %0,%1,0x64\n" |
153 | #endif | ||
154 | " ipm %2\n" | 242 | " ipm %2\n" |
155 | " srl %2,28\n" | 243 | " srl %2,28\n" |
156 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | 244 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); |
245 | #endif | ||
157 | *ret1 = rx; | 246 | *ret1 = rx; |
158 | *ret2 = ry; | 247 | *ret2 = ry; |
159 | return rc; | 248 | return rc; |
@@ -190,14 +279,45 @@ query_segment_type (struct dcss_segment *seg) | |||
190 | qin->qoutlen = sizeof(struct qout64); | 279 | qin->qoutlen = sizeof(struct qout64); |
191 | memcpy (qin->qname, seg->dcss_name, 8); | 280 | memcpy (qin->qname, seg->dcss_name, 8); |
192 | 281 | ||
193 | diag_cc = dcss_diag (DCSS_SEGEXT, qin, &dummy, &vmrc); | 282 | diag_cc = dcss_diag(&segext_scode, qin, &dummy, &vmrc); |
194 | 283 | ||
284 | if (diag_cc < 0) { | ||
285 | rc = diag_cc; | ||
286 | goto out_free; | ||
287 | } | ||
195 | if (diag_cc > 1) { | 288 | if (diag_cc > 1) { |
196 | PRINT_WARN ("segment_type: diag returned error %ld\n", vmrc); | 289 | PRINT_WARN ("segment_type: diag returned error %ld\n", vmrc); |
197 | rc = dcss_diag_translate_rc (vmrc); | 290 | rc = dcss_diag_translate_rc (vmrc); |
198 | goto out_free; | 291 | goto out_free; |
199 | } | 292 | } |
200 | 293 | ||
294 | #ifdef CONFIG_64BIT | ||
295 | /* Only old format of output area of Diagnose x'64' is supported, | ||
296 | copy data for the new format. */ | ||
297 | if (segext_scode == DCSS_SEGEXT) { | ||
298 | struct qout64_old *qout_old; | ||
299 | qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA); | ||
300 | if (qout_old == NULL) { | ||
301 | rc = -ENOMEM; | ||
302 | goto out_free; | ||
303 | } | ||
304 | memcpy(qout_old, qout, sizeof(struct qout64_old)); | ||
305 | qout->segstart = (unsigned long) qout_old->segstart; | ||
306 | qout->segend = (unsigned long) qout_old->segend; | ||
307 | qout->segcnt = qout_old->segcnt; | ||
308 | qout->segrcnt = qout_old->segrcnt; | ||
309 | |||
310 | if (qout->segcnt > 6) | ||
311 | qout->segrcnt = 6; | ||
312 | for (i = 0; i < qout->segrcnt; i++) { | ||
313 | qout->range[i].start = | ||
314 | (unsigned long) qout_old->range[i].start; | ||
315 | qout->range[i].end = | ||
316 | (unsigned long) qout_old->range[i].end; | ||
317 | } | ||
318 | kfree(qout_old); | ||
319 | } | ||
320 | #endif | ||
201 | if (qout->segcnt > 6) { | 321 | if (qout->segcnt > 6) { |
202 | rc = -ENOTSUPP; | 322 | rc = -ENOTSUPP; |
203 | goto out_free; | 323 | goto out_free; |
@@ -269,6 +389,30 @@ segment_type (char* name) | |||
269 | } | 389 | } |
270 | 390 | ||
271 | /* | 391 | /* |
392 | * check if segment collides with other segments that are currently loaded | ||
393 | * returns 1 if this is the case, 0 if no collision was found | ||
394 | */ | ||
395 | static int | ||
396 | segment_overlaps_others (struct dcss_segment *seg) | ||
397 | { | ||
398 | struct list_head *l; | ||
399 | struct dcss_segment *tmp; | ||
400 | |||
401 | BUG_ON(!mutex_is_locked(&dcss_lock)); | ||
402 | list_for_each(l, &dcss_list) { | ||
403 | tmp = list_entry(l, struct dcss_segment, list); | ||
404 | if ((tmp->start_addr >> 20) > (seg->end >> 20)) | ||
405 | continue; | ||
406 | if ((tmp->end >> 20) < (seg->start_addr >> 20)) | ||
407 | continue; | ||
408 | if (seg == tmp) | ||
409 | continue; | ||
410 | return 1; | ||
411 | } | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | /* | ||
272 | * real segment loading function, called from segment_load | 416 | * real segment loading function, called from segment_load |
273 | */ | 417 | */ |
274 | static int | 418 | static int |
@@ -276,7 +420,8 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
276 | { | 420 | { |
277 | struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), | 421 | struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), |
278 | GFP_DMA); | 422 | GFP_DMA); |
279 | int dcss_command, rc, diag_cc; | 423 | int rc, diag_cc; |
424 | unsigned long start_addr, end_addr, dummy; | ||
280 | 425 | ||
281 | if (seg == NULL) { | 426 | if (seg == NULL) { |
282 | rc = -ENOMEM; | 427 | rc = -ENOMEM; |
@@ -287,6 +432,13 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
287 | if (rc < 0) | 432 | if (rc < 0) |
288 | goto out_free; | 433 | goto out_free; |
289 | 434 | ||
435 | if (loadshr_scode == DCSS_LOADSHRX) { | ||
436 | if (segment_overlaps_others(seg)) { | ||
437 | rc = -EBUSY; | ||
438 | goto out_free; | ||
439 | } | ||
440 | } | ||
441 | |||
290 | rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1); | 442 | rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1); |
291 | 443 | ||
292 | if (rc) | 444 | if (rc) |
@@ -316,20 +468,28 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
316 | } | 468 | } |
317 | 469 | ||
318 | if (do_nonshared) | 470 | if (do_nonshared) |
319 | dcss_command = DCSS_LOADNSR; | 471 | diag_cc = dcss_diag(&loadnsr_scode, seg->dcss_name, |
472 | &start_addr, &end_addr); | ||
320 | else | 473 | else |
321 | dcss_command = DCSS_LOADNOLY; | 474 | diag_cc = dcss_diag(&loadshr_scode, seg->dcss_name, |
322 | 475 | &start_addr, &end_addr); | |
323 | diag_cc = dcss_diag(dcss_command, seg->dcss_name, | 476 | if (diag_cc < 0) { |
324 | &seg->start_addr, &seg->end); | 477 | dcss_diag(&purgeseg_scode, seg->dcss_name, |
478 | &dummy, &dummy); | ||
479 | rc = diag_cc; | ||
480 | goto out_resource; | ||
481 | } | ||
325 | if (diag_cc > 1) { | 482 | if (diag_cc > 1) { |
326 | PRINT_WARN ("segment_load: could not load segment %s - " | 483 | PRINT_WARN ("segment_load: could not load segment %s - " |
327 | "diag returned error (%ld)\n",name,seg->end); | 484 | "diag returned error (%ld)\n", |
328 | rc = dcss_diag_translate_rc (seg->end); | 485 | name, end_addr); |
329 | dcss_diag(DCSS_PURGESEG, seg->dcss_name, | 486 | rc = dcss_diag_translate_rc(end_addr); |
330 | &seg->start_addr, &seg->end); | 487 | dcss_diag(&purgeseg_scode, seg->dcss_name, |
488 | &dummy, &dummy); | ||
331 | goto out_resource; | 489 | goto out_resource; |
332 | } | 490 | } |
491 | seg->start_addr = start_addr; | ||
492 | seg->end = end_addr; | ||
333 | seg->do_nonshared = do_nonshared; | 493 | seg->do_nonshared = do_nonshared; |
334 | atomic_set(&seg->ref_count, 1); | 494 | atomic_set(&seg->ref_count, 1); |
335 | list_add(&seg->list, &dcss_list); | 495 | list_add(&seg->list, &dcss_list); |
@@ -423,8 +583,8 @@ int | |||
423 | segment_modify_shared (char *name, int do_nonshared) | 583 | segment_modify_shared (char *name, int do_nonshared) |
424 | { | 584 | { |
425 | struct dcss_segment *seg; | 585 | struct dcss_segment *seg; |
426 | unsigned long dummy; | 586 | unsigned long start_addr, end_addr, dummy; |
427 | int dcss_command, rc, diag_cc; | 587 | int rc, diag_cc; |
428 | 588 | ||
429 | mutex_lock(&dcss_lock); | 589 | mutex_lock(&dcss_lock); |
430 | seg = segment_by_name (name); | 590 | seg = segment_by_name (name); |
@@ -445,38 +605,51 @@ segment_modify_shared (char *name, int do_nonshared) | |||
445 | goto out_unlock; | 605 | goto out_unlock; |
446 | } | 606 | } |
447 | release_resource(seg->res); | 607 | release_resource(seg->res); |
448 | if (do_nonshared) { | 608 | if (do_nonshared) |
449 | dcss_command = DCSS_LOADNSR; | ||
450 | seg->res->flags &= ~IORESOURCE_READONLY; | 609 | seg->res->flags &= ~IORESOURCE_READONLY; |
451 | } else { | 610 | else |
452 | dcss_command = DCSS_LOADNOLY; | ||
453 | if (seg->vm_segtype == SEG_TYPE_SR || | 611 | if (seg->vm_segtype == SEG_TYPE_SR || |
454 | seg->vm_segtype == SEG_TYPE_ER) | 612 | seg->vm_segtype == SEG_TYPE_ER) |
455 | seg->res->flags |= IORESOURCE_READONLY; | 613 | seg->res->flags |= IORESOURCE_READONLY; |
456 | } | 614 | |
457 | if (request_resource(&iomem_resource, seg->res)) { | 615 | if (request_resource(&iomem_resource, seg->res)) { |
458 | PRINT_WARN("segment_modify_shared: could not reload segment %s" | 616 | PRINT_WARN("segment_modify_shared: could not reload segment %s" |
459 | " - overlapping resources\n", name); | 617 | " - overlapping resources\n", name); |
460 | rc = -EBUSY; | 618 | rc = -EBUSY; |
461 | kfree(seg->res); | 619 | kfree(seg->res); |
462 | goto out_del; | 620 | goto out_del_mem; |
621 | } | ||
622 | |||
623 | dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy); | ||
624 | if (do_nonshared) | ||
625 | diag_cc = dcss_diag(&loadnsr_scode, seg->dcss_name, | ||
626 | &start_addr, &end_addr); | ||
627 | else | ||
628 | diag_cc = dcss_diag(&loadshr_scode, seg->dcss_name, | ||
629 | &start_addr, &end_addr); | ||
630 | if (diag_cc < 0) { | ||
631 | rc = diag_cc; | ||
632 | goto out_del_res; | ||
463 | } | 633 | } |
464 | dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); | ||
465 | diag_cc = dcss_diag(dcss_command, seg->dcss_name, | ||
466 | &seg->start_addr, &seg->end); | ||
467 | if (diag_cc > 1) { | 634 | if (diag_cc > 1) { |
468 | PRINT_WARN ("segment_modify_shared: could not reload segment %s" | 635 | PRINT_WARN ("segment_modify_shared: could not reload segment %s" |
469 | " - diag returned error (%ld)\n",name,seg->end); | 636 | " - diag returned error (%ld)\n", |
470 | rc = dcss_diag_translate_rc (seg->end); | 637 | name, end_addr); |
471 | goto out_del; | 638 | rc = dcss_diag_translate_rc(end_addr); |
639 | goto out_del_res; | ||
472 | } | 640 | } |
641 | seg->start_addr = start_addr; | ||
642 | seg->end = end_addr; | ||
473 | seg->do_nonshared = do_nonshared; | 643 | seg->do_nonshared = do_nonshared; |
474 | rc = 0; | 644 | rc = 0; |
475 | goto out_unlock; | 645 | goto out_unlock; |
476 | out_del: | 646 | out_del_res: |
647 | release_resource(seg->res); | ||
648 | kfree(seg->res); | ||
649 | out_del_mem: | ||
477 | vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); | 650 | vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); |
478 | list_del(&seg->list); | 651 | list_del(&seg->list); |
479 | dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); | 652 | dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy); |
480 | kfree(seg); | 653 | kfree(seg); |
481 | out_unlock: | 654 | out_unlock: |
482 | mutex_unlock(&dcss_lock); | 655 | mutex_unlock(&dcss_lock); |
@@ -510,7 +683,7 @@ segment_unload(char *name) | |||
510 | kfree(seg->res); | 683 | kfree(seg->res); |
511 | vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); | 684 | vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); |
512 | list_del(&seg->list); | 685 | list_del(&seg->list); |
513 | dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); | 686 | dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy); |
514 | kfree(seg); | 687 | kfree(seg); |
515 | out_unlock: | 688 | out_unlock: |
516 | mutex_unlock(&dcss_lock); | 689 | mutex_unlock(&dcss_lock); |
@@ -545,7 +718,7 @@ segment_save(char *name) | |||
545 | endpfn = (seg->end) >> PAGE_SHIFT; | 718 | endpfn = (seg->end) >> PAGE_SHIFT; |
546 | sprintf(cmd1, "DEFSEG %s", name); | 719 | sprintf(cmd1, "DEFSEG %s", name); |
547 | for (i=0; i<seg->segcnt; i++) { | 720 | for (i=0; i<seg->segcnt; i++) { |
548 | sprintf(cmd1+strlen(cmd1), " %X-%X %s", | 721 | sprintf(cmd1+strlen(cmd1), " %lX-%lX %s", |
549 | seg->range[i].start >> PAGE_SHIFT, | 722 | seg->range[i].start >> PAGE_SHIFT, |
550 | seg->range[i].end >> PAGE_SHIFT, | 723 | seg->range[i].end >> PAGE_SHIFT, |
551 | segtype_string[seg->range[i].start & 0xff]); | 724 | segtype_string[seg->range[i].start & 0xff]); |