diff options
-rw-r--r-- | Documentation/s390/CommonIO | 2 | ||||
-rw-r--r-- | Documentation/s390/cds.txt | 52 | ||||
-rw-r--r-- | Documentation/s390/driver-model.txt | 3 | ||||
-rw-r--r-- | arch/s390/defconfig | 12 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/syscalls.S | 1 | ||||
-rw-r--r-- | drivers/s390/block/dasd.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/monwriter.c | 14 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 2 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 50 | ||||
-rw-r--r-- | include/asm-s390/unistd.h | 3 |
12 files changed, 94 insertions, 52 deletions
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO index 59d1166d41ee..d684a6ac69a8 100644 --- a/Documentation/s390/CommonIO +++ b/Documentation/s390/CommonIO | |||
@@ -66,7 +66,7 @@ Command line parameters | |||
66 | 66 | ||
67 | When a device is un-ignored, device recognition and sensing is performed and | 67 | When a device is un-ignored, device recognition and sensing is performed and |
68 | the device driver will be notified if possible, so the device will become | 68 | the device driver will be notified if possible, so the device will become |
69 | available to the system. | 69 | available to the system. Note that un-ignoring is performed asynchronously. |
70 | 70 | ||
71 | You can also add ranges of devices to be ignored by piping to | 71 | You can also add ranges of devices to be ignored by piping to |
72 | /proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the | 72 | /proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the |
diff --git a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt index d80e5733827d..32a96cc39215 100644 --- a/Documentation/s390/cds.txt +++ b/Documentation/s390/cds.txt | |||
@@ -174,14 +174,10 @@ read_dev_chars() - Read Device Characteristics | |||
174 | 174 | ||
175 | This routine returns the characteristics for the device specified. | 175 | This routine returns the characteristics for the device specified. |
176 | 176 | ||
177 | The function is meant to be called with an irq handler in place; that is, | 177 | The function is meant to be called with the device already enabled; that is, |
178 | at earliest during set_online() processing. | 178 | at earliest during set_online() processing. |
179 | 179 | ||
180 | While the request is processed synchronously, the device interrupt | 180 | The ccw_device must not be locked prior to calling read_dev_chars(). |
181 | handler is called for final ending status. In case of error situations the | ||
182 | interrupt handler may recover appropriately. The device irq handler can | ||
183 | recognize the corresponding interrupts by the interruption parameter be | ||
184 | 0x00524443. The ccw_device must not be locked prior to calling read_dev_chars(). | ||
185 | 181 | ||
186 | The function may be called enabled or disabled. | 182 | The function may be called enabled or disabled. |
187 | 183 | ||
@@ -410,26 +406,7 @@ individual flag meanings. | |||
410 | 406 | ||
411 | Usage Notes : | 407 | Usage Notes : |
412 | 408 | ||
413 | Prior to call ccw_device_start() the device driver must assure disabled state, | 409 | ccw_device_start() must be called disabled and with the ccw device lock held. |
414 | i.e. the I/O mask value in the PSW must be disabled. This can be accomplished | ||
415 | by calling local_save_flags( flags). The current PSW flags are preserved and | ||
416 | can be restored by local_irq_restore( flags) at a later time. | ||
417 | |||
418 | If the device driver violates this rule while running in a uni-processor | ||
419 | environment an interrupt might be presented prior to the ccw_device_start() | ||
420 | routine returning to the device driver main path. In this case we will end in a | ||
421 | deadlock situation as the interrupt handler will try to obtain the irq | ||
422 | lock the device driver still owns (see below) ! | ||
423 | |||
424 | The driver must assure to hold the device specific lock. This can be | ||
425 | accomplished by | ||
426 | |||
427 | (i) spin_lock(get_ccwdev_lock(cdev)), or | ||
428 | (ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags) | ||
429 | |||
430 | Option (i) should be used if the calling routine is running disabled for | ||
431 | I/O interrupts (see above) already. Option (ii) obtains the device gate und | ||
432 | puts the CPU into I/O disabled state by preserving the current PSW flags. | ||
433 | 410 | ||
434 | The device driver is allowed to issue the next ccw_device_start() call from | 411 | The device driver is allowed to issue the next ccw_device_start() call from |
435 | within its interrupt handler already. It is not required to schedule a | 412 | within its interrupt handler already. It is not required to schedule a |
@@ -488,7 +465,7 @@ int ccw_device_resume(struct ccw_device *cdev); | |||
488 | 465 | ||
489 | cdev - ccw_device the resume operation is requested for | 466 | cdev - ccw_device the resume operation is requested for |
490 | 467 | ||
491 | The resume_IO() function returns: | 468 | The ccw_device_resume() function returns: |
492 | 469 | ||
493 | 0 - suspended channel program is resumed | 470 | 0 - suspended channel program is resumed |
494 | -EBUSY - status pending | 471 | -EBUSY - status pending |
@@ -507,6 +484,8 @@ a long-running channel program or the device might require to initially issue | |||
507 | a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt() | 484 | a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt() |
508 | command is provided. | 485 | command is provided. |
509 | 486 | ||
487 | ccw_device_halt() must be called disabled and with the ccw device lock held. | ||
488 | |||
510 | int ccw_device_halt(struct ccw_device *cdev, | 489 | int ccw_device_halt(struct ccw_device *cdev, |
511 | unsigned long intparm); | 490 | unsigned long intparm); |
512 | 491 | ||
@@ -517,7 +496,7 @@ intparm : interruption parameter; value is only used if no I/O | |||
517 | 496 | ||
518 | The ccw_device_halt() function returns : | 497 | The ccw_device_halt() function returns : |
519 | 498 | ||
520 | 0 - successful completion or request successfully initiated | 499 | 0 - request successfully initiated |
521 | -EBUSY - the device is currently busy, or status pending. | 500 | -EBUSY - the device is currently busy, or status pending. |
522 | -ENODEV - cdev invalid. | 501 | -ENODEV - cdev invalid. |
523 | -EINVAL - The device is not operational or the ccw device is not online. | 502 | -EINVAL - The device is not operational or the ccw device is not online. |
@@ -533,6 +512,23 @@ can then perform an appropriate action. Prior to interrupt of an outstanding | |||
533 | read to a network device (with or without PCI flag) a ccw_device_halt() | 512 | read to a network device (with or without PCI flag) a ccw_device_halt() |
534 | is required to end the pending operation. | 513 | is required to end the pending operation. |
535 | 514 | ||
515 | ccw_device_clear() - Terminage I/O Request Processing | ||
516 | |||
517 | In order to terminate all I/O processing at the subchannel, the clear subchannel | ||
518 | (CSCH) command is used. It can be issued via ccw_device_clear(). | ||
519 | |||
520 | ccw_device_clear() must be called disabled and with the ccw device lock held. | ||
521 | |||
522 | int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm); | ||
523 | |||
524 | cdev: ccw_device the clear operation is requested for | ||
525 | intparm: interruption parameter (see ccw_device_halt()) | ||
526 | |||
527 | The ccw_device_clear() function returns: | ||
528 | |||
529 | 0 - request successfully initiated | ||
530 | -ENODEV - cdev invalid | ||
531 | -EINVAL - The device is not operational or the ccw device is not online. | ||
536 | 532 | ||
537 | Miscellaneous Support Routines | 533 | Miscellaneous Support Routines |
538 | 534 | ||
diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt index 62c082387aea..77bf450ec39b 100644 --- a/Documentation/s390/driver-model.txt +++ b/Documentation/s390/driver-model.txt | |||
@@ -239,6 +239,9 @@ status - Can be 'online' or 'offline'. | |||
239 | 239 | ||
240 | type - The physical type of the channel path. | 240 | type - The physical type of the channel path. |
241 | 241 | ||
242 | shared - Whether the channel path is shared. | ||
243 | |||
244 | cmg - The channel measurement group. | ||
242 | 245 | ||
243 | 3. System devices | 246 | 3. System devices |
244 | ----------------- | 247 | ----------------- |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index a3257398ea8d..c313e9a9304f 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.18 | 3 | # Linux kernel version: 2.6.19-rc2 |
4 | # Wed Oct 4 19:45:46 2006 | 4 | # Wed Oct 18 17:11:10 2006 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_LOCKDEP_SUPPORT=y | 7 | CONFIG_LOCKDEP_SUPPORT=y |
@@ -211,6 +211,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y | |||
211 | CONFIG_INET6_XFRM_MODE_TUNNEL=y | 211 | CONFIG_INET6_XFRM_MODE_TUNNEL=y |
212 | CONFIG_INET6_XFRM_MODE_BEET=y | 212 | CONFIG_INET6_XFRM_MODE_BEET=y |
213 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set | 213 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set |
214 | CONFIG_IPV6_SIT=y | ||
214 | # CONFIG_IPV6_TUNNEL is not set | 215 | # CONFIG_IPV6_TUNNEL is not set |
215 | # CONFIG_IPV6_SUBTREES is not set | 216 | # CONFIG_IPV6_SUBTREES is not set |
216 | # CONFIG_IPV6_MULTIPLE_TABLES is not set | 217 | # CONFIG_IPV6_MULTIPLE_TABLES is not set |
@@ -528,6 +529,7 @@ CONFIG_EXT3_FS=y | |||
528 | CONFIG_EXT3_FS_XATTR=y | 529 | CONFIG_EXT3_FS_XATTR=y |
529 | # CONFIG_EXT3_FS_POSIX_ACL is not set | 530 | # CONFIG_EXT3_FS_POSIX_ACL is not set |
530 | # CONFIG_EXT3_FS_SECURITY is not set | 531 | # CONFIG_EXT3_FS_SECURITY is not set |
532 | # CONFIG_EXT4DEV_FS is not set | ||
531 | CONFIG_JBD=y | 533 | CONFIG_JBD=y |
532 | # CONFIG_JBD_DEBUG is not set | 534 | # CONFIG_JBD_DEBUG is not set |
533 | CONFIG_FS_MBCACHE=y | 535 | CONFIG_FS_MBCACHE=y |
@@ -646,10 +648,6 @@ CONFIG_MSDOS_PARTITION=y | |||
646 | # CONFIG_NLS is not set | 648 | # CONFIG_NLS is not set |
647 | 649 | ||
648 | # | 650 | # |
649 | # Distributed Lock Manager | ||
650 | # | ||
651 | |||
652 | # | ||
653 | # Instrumentation Support | 651 | # Instrumentation Support |
654 | # | 652 | # |
655 | 653 | ||
@@ -669,7 +667,6 @@ CONFIG_MAGIC_SYSRQ=y | |||
669 | # CONFIG_UNUSED_SYMBOLS is not set | 667 | # CONFIG_UNUSED_SYMBOLS is not set |
670 | CONFIG_DEBUG_KERNEL=y | 668 | CONFIG_DEBUG_KERNEL=y |
671 | CONFIG_LOG_BUF_SHIFT=17 | 669 | CONFIG_LOG_BUF_SHIFT=17 |
672 | # CONFIG_DETECT_SOFTLOCKUP is not set | ||
673 | # CONFIG_SCHEDSTATS is not set | 670 | # CONFIG_SCHEDSTATS is not set |
674 | # CONFIG_DEBUG_SLAB is not set | 671 | # CONFIG_DEBUG_SLAB is not set |
675 | CONFIG_DEBUG_PREEMPT=y | 672 | CONFIG_DEBUG_PREEMPT=y |
@@ -690,6 +687,7 @@ CONFIG_DEBUG_FS=y | |||
690 | # CONFIG_FRAME_POINTER is not set | 687 | # CONFIG_FRAME_POINTER is not set |
691 | # CONFIG_UNWIND_INFO is not set | 688 | # CONFIG_UNWIND_INFO is not set |
692 | CONFIG_FORCED_INLINING=y | 689 | CONFIG_FORCED_INLINING=y |
690 | CONFIG_HEADERS_CHECK=y | ||
693 | # CONFIG_RCU_TORTURE_TEST is not set | 691 | # CONFIG_RCU_TORTURE_TEST is not set |
694 | # CONFIG_LKDTM is not set | 692 | # CONFIG_LKDTM is not set |
695 | 693 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index e15e1489aef5..2001767e1dc7 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -295,6 +295,7 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) | |||
295 | * | 295 | * |
296 | * This is really horribly ugly. | 296 | * This is really horribly ugly. |
297 | */ | 297 | */ |
298 | #ifdef CONFIG_SYSVIPC | ||
298 | asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) | 299 | asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) |
299 | { | 300 | { |
300 | if (call >> 16) /* hack for backward compatibility */ | 301 | if (call >> 16) /* hack for backward compatibility */ |
@@ -338,6 +339,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) | |||
338 | 339 | ||
339 | return -ENOSYS; | 340 | return -ENOSYS; |
340 | } | 341 | } |
342 | #endif | ||
341 | 343 | ||
342 | asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) | 344 | asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) |
343 | { | 345 | { |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index e59baec56520..a4ceae3dbcf1 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -320,3 +320,4 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) | |||
320 | SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) | 320 | SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) |
321 | NI_SYSCALL /* 310 sys_move_pages */ | 321 | NI_SYSCALL /* 310 sys_move_pages */ |
322 | SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) | 322 | SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) |
323 | SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall) | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d0647d116eaa..79ffef6bfaf8 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -203,6 +203,7 @@ dasd_state_basic_to_known(struct dasd_device * device) | |||
203 | rc = dasd_flush_ccw_queue(device, 1); | 203 | rc = dasd_flush_ccw_queue(device, 1); |
204 | if (rc) | 204 | if (rc) |
205 | return rc; | 205 | return rc; |
206 | dasd_clear_timer(device); | ||
206 | 207 | ||
207 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); | 208 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); |
208 | if (device->debug_area != NULL) { | 209 | if (device->debug_area != NULL) { |
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index abd02ed501cb..b9b0fc3f812b 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c | |||
@@ -73,12 +73,15 @@ static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv, | |||
73 | struct mon_buf *entry, *next; | 73 | struct mon_buf *entry, *next; |
74 | 74 | ||
75 | list_for_each_entry_safe(entry, next, &monpriv->list, list) | 75 | list_for_each_entry_safe(entry, next, &monpriv->list, list) |
76 | if (entry->hdr.applid == monhdr->applid && | 76 | if ((entry->hdr.mon_function == monhdr->mon_function || |
77 | monhdr->mon_function == MONWRITE_STOP_INTERVAL) && | ||
78 | entry->hdr.applid == monhdr->applid && | ||
77 | entry->hdr.record_num == monhdr->record_num && | 79 | entry->hdr.record_num == monhdr->record_num && |
78 | entry->hdr.version == monhdr->version && | 80 | entry->hdr.version == monhdr->version && |
79 | entry->hdr.release == monhdr->release && | 81 | entry->hdr.release == monhdr->release && |
80 | entry->hdr.mod_level == monhdr->mod_level) | 82 | entry->hdr.mod_level == monhdr->mod_level) |
81 | return entry; | 83 | return entry; |
84 | |||
82 | return NULL; | 85 | return NULL; |
83 | } | 86 | } |
84 | 87 | ||
@@ -92,7 +95,9 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
92 | monhdr->mon_function > MONWRITE_START_CONFIG || | 95 | monhdr->mon_function > MONWRITE_START_CONFIG || |
93 | monhdr->hdrlen != sizeof(struct monwrite_hdr)) | 96 | monhdr->hdrlen != sizeof(struct monwrite_hdr)) |
94 | return -EINVAL; | 97 | return -EINVAL; |
95 | monbuf = monwrite_find_hdr(monpriv, monhdr); | 98 | monbuf = NULL; |
99 | if (monhdr->mon_function != MONWRITE_GEN_EVENT) | ||
100 | monbuf = monwrite_find_hdr(monpriv, monhdr); | ||
96 | if (monbuf) { | 101 | if (monbuf) { |
97 | if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) { | 102 | if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) { |
98 | monhdr->datalen = monbuf->hdr.datalen; | 103 | monhdr->datalen = monbuf->hdr.datalen; |
@@ -104,7 +109,7 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
104 | kfree(monbuf); | 109 | kfree(monbuf); |
105 | monbuf = NULL; | 110 | monbuf = NULL; |
106 | } | 111 | } |
107 | } else { | 112 | } else if (monhdr->mon_function != MONWRITE_STOP_INTERVAL) { |
108 | if (mon_buf_count >= mon_max_bufs) | 113 | if (mon_buf_count >= mon_max_bufs) |
109 | return -ENOSPC; | 114 | return -ENOSPC; |
110 | monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); | 115 | monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); |
@@ -118,7 +123,8 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
118 | } | 123 | } |
119 | monbuf->hdr = *monhdr; | 124 | monbuf->hdr = *monhdr; |
120 | list_add_tail(&monbuf->list, &monpriv->list); | 125 | list_add_tail(&monbuf->list, &monpriv->list); |
121 | mon_buf_count++; | 126 | if (monhdr->mon_function != MONWRITE_GEN_EVENT) |
127 | mon_buf_count++; | ||
122 | } | 128 | } |
123 | monpriv->current_buf = monbuf; | 129 | monpriv->current_buf = monbuf; |
124 | return 0; | 130 | return 0; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index fcaf28d7b4eb..de3d0857db9f 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -578,9 +578,13 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
578 | } | 578 | } |
579 | break; | 579 | break; |
580 | case -ETIME: | 580 | case -ETIME: |
581 | /* Reset oper notify indication after verify error. */ | ||
582 | cdev->private->flags.donotify = 0; | ||
581 | ccw_device_done(cdev, DEV_STATE_BOXED); | 583 | ccw_device_done(cdev, DEV_STATE_BOXED); |
582 | break; | 584 | break; |
583 | default: | 585 | default: |
586 | /* Reset oper notify indication after verify error. */ | ||
587 | cdev->private->flags.donotify = 0; | ||
584 | PREPARE_WORK(&cdev->private->kick_work, | 588 | PREPARE_WORK(&cdev->private->kick_work, |
585 | ccw_device_nopath_notify, cdev); | 589 | ccw_device_nopath_notify, cdev); |
586 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | 590 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 0648ce5bb684..476aa1da5cbc 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -3529,7 +3529,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, | |||
3529 | #ifdef CONFIG_QDIO_DEBUG | 3529 | #ifdef CONFIG_QDIO_DEBUG |
3530 | char dbf_text[20]; | 3530 | char dbf_text[20]; |
3531 | 3531 | ||
3532 | sprintf(dbf_text,"doQD%04x",cdev->private->sch_no); | 3532 | sprintf(dbf_text,"doQD%04x",cdev->private->schid.sch_no); |
3533 | QDIO_DBF_TEXT3(0,trace,dbf_text); | 3533 | QDIO_DBF_TEXT3(0,trace,dbf_text); |
3534 | #endif /* CONFIG_QDIO_DEBUG */ | 3534 | #endif /* CONFIG_QDIO_DEBUG */ |
3535 | 3535 | ||
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 519f0a5ff181..36bb6dacf008 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
@@ -200,18 +200,45 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
200 | */ | 200 | */ |
201 | 201 | ||
202 | /* Hardware bits in the page table entry */ | 202 | /* Hardware bits in the page table entry */ |
203 | #define _PAGE_RO 0x200 /* HW read-only */ | 203 | #define _PAGE_RO 0x200 /* HW read-only bit */ |
204 | #define _PAGE_INVALID 0x400 /* HW invalid */ | 204 | #define _PAGE_INVALID 0x400 /* HW invalid bit */ |
205 | #define _PAGE_SWT 0x001 /* SW pte type bit t */ | ||
206 | #define _PAGE_SWX 0x002 /* SW pte type bit x */ | ||
205 | 207 | ||
206 | /* Mask and six different types of pages. */ | 208 | /* Six different types of pages. */ |
207 | #define _PAGE_TYPE_MASK 0x601 | ||
208 | #define _PAGE_TYPE_EMPTY 0x400 | 209 | #define _PAGE_TYPE_EMPTY 0x400 |
209 | #define _PAGE_TYPE_NONE 0x401 | 210 | #define _PAGE_TYPE_NONE 0x401 |
210 | #define _PAGE_TYPE_SWAP 0x600 | 211 | #define _PAGE_TYPE_SWAP 0x403 |
211 | #define _PAGE_TYPE_FILE 0x601 | 212 | #define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */ |
212 | #define _PAGE_TYPE_RO 0x200 | 213 | #define _PAGE_TYPE_RO 0x200 |
213 | #define _PAGE_TYPE_RW 0x000 | 214 | #define _PAGE_TYPE_RW 0x000 |
214 | 215 | ||
216 | /* | ||
217 | * PTE type bits are rather complicated. handle_pte_fault uses pte_present, | ||
218 | * pte_none and pte_file to find out the pte type WITHOUT holding the page | ||
219 | * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to | ||
220 | * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs | ||
221 | * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards. | ||
222 | * This change is done while holding the lock, but the intermediate step | ||
223 | * of a previously valid pte with the hw invalid bit set can be observed by | ||
224 | * handle_pte_fault. That makes it necessary that all valid pte types with | ||
225 | * the hw invalid bit set must be distinguishable from the four pte types | ||
226 | * empty, none, swap and file. | ||
227 | * | ||
228 | * irxt ipte irxt | ||
229 | * _PAGE_TYPE_EMPTY 1000 -> 1000 | ||
230 | * _PAGE_TYPE_NONE 1001 -> 1001 | ||
231 | * _PAGE_TYPE_SWAP 1011 -> 1011 | ||
232 | * _PAGE_TYPE_FILE 11?1 -> 11?1 | ||
233 | * _PAGE_TYPE_RO 0100 -> 1100 | ||
234 | * _PAGE_TYPE_RW 0000 -> 1000 | ||
235 | * | ||
236 | * pte_none is true for bits combinations 1000, 1100 | ||
237 | * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001 | ||
238 | * pte_file is true for bits combinations 1101, 1111 | ||
239 | * swap pte is 1011 and 0001, 0011, 0101, 0111, 1010 and 1110 are invalid. | ||
240 | */ | ||
241 | |||
215 | #ifndef __s390x__ | 242 | #ifndef __s390x__ |
216 | 243 | ||
217 | /* Bits in the segment table entry */ | 244 | /* Bits in the segment table entry */ |
@@ -365,18 +392,21 @@ static inline int pmd_bad(pmd_t pmd) | |||
365 | 392 | ||
366 | static inline int pte_none(pte_t pte) | 393 | static inline int pte_none(pte_t pte) |
367 | { | 394 | { |
368 | return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_EMPTY; | 395 | return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT); |
369 | } | 396 | } |
370 | 397 | ||
371 | static inline int pte_present(pte_t pte) | 398 | static inline int pte_present(pte_t pte) |
372 | { | 399 | { |
373 | return !(pte_val(pte) & _PAGE_INVALID) || | 400 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX; |
374 | (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_NONE; | 401 | return (pte_val(pte) & mask) == _PAGE_TYPE_NONE || |
402 | (!(pte_val(pte) & _PAGE_INVALID) && | ||
403 | !(pte_val(pte) & _PAGE_SWT)); | ||
375 | } | 404 | } |
376 | 405 | ||
377 | static inline int pte_file(pte_t pte) | 406 | static inline int pte_file(pte_t pte) |
378 | { | 407 | { |
379 | return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_FILE; | 408 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT; |
409 | return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; | ||
380 | } | 410 | } |
381 | 411 | ||
382 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) | 412 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) |
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index a19238cbcffa..71d3c21b84f0 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h | |||
@@ -249,8 +249,9 @@ | |||
249 | #define __NR_vmsplice 309 | 249 | #define __NR_vmsplice 309 |
250 | /* Number 310 is reserved for new sys_move_pages */ | 250 | /* Number 310 is reserved for new sys_move_pages */ |
251 | #define __NR_getcpu 311 | 251 | #define __NR_getcpu 311 |
252 | #define __NR_epoll_pwait 312 | ||
252 | 253 | ||
253 | #define NR_syscalls 312 | 254 | #define NR_syscalls 313 |
254 | 255 | ||
255 | /* | 256 | /* |
256 | * There are some system calls that are not present on 64 bit, some | 257 | * There are some system calls that are not present on 64 bit, some |