diff options
27 files changed, 408 insertions, 387 deletions
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO index 8fbc0a852870..bf0baa19ec24 100644 --- a/Documentation/s390/CommonIO +++ b/Documentation/s390/CommonIO | |||
| @@ -8,17 +8,6 @@ Command line parameters | |||
| 8 | 8 | ||
| 9 | Enable logging of debug information in case of ccw device timeouts. | 9 | Enable logging of debug information in case of ccw device timeouts. |
| 10 | 10 | ||
| 11 | |||
| 12 | * cio_msg = yes | no | ||
| 13 | |||
| 14 | Determines whether information on found devices and sensed device | ||
| 15 | characteristics should be shown during startup or when new devices are | ||
| 16 | found, i. e. messages of the types "Detected device 0.0.4711 on subchannel | ||
| 17 | 0.0.0042" and "SenseID: Device 0.0.4711 reports: ...". | ||
| 18 | |||
| 19 | Default is off. | ||
| 20 | |||
| 21 | |||
| 22 | * cio_ignore = {all} | | 11 | * cio_ignore = {all} | |
| 23 | {<device> | <range of devices>} | | 12 | {<device> | <range of devices>} | |
| 24 | {!<device> | !<range of devices>} | 13 | {!<device> | !<range of devices>} |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 29a7940f284f..1d035082e78e 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -430,6 +430,13 @@ config CMM_IUCV | |||
| 430 | Select this option to enable the special message interface to | 430 | Select this option to enable the special message interface to |
| 431 | the cooperative memory management. | 431 | the cooperative memory management. |
| 432 | 432 | ||
| 433 | config PAGE_STATES | ||
| 434 | bool "Unused page notification" | ||
| 435 | help | ||
| 436 | This enables the notification of unused pages to the | ||
| 437 | hypervisor. The ESSA instruction is used to do the states | ||
| 438 | changes between a page that has content and the unused state. | ||
| 439 | |||
| 433 | config VIRT_TIMER | 440 | config VIRT_TIMER |
| 434 | bool "Virtual CPU timer support" | 441 | bool "Virtual CPU timer support" |
| 435 | help | 442 | help |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 743d54f0b8db..d003a6e16afb 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
| @@ -121,7 +121,7 @@ sys32_ptrace_wrapper: | |||
| 121 | lgfr %r3,%r3 # long | 121 | lgfr %r3,%r3 # long |
| 122 | llgtr %r4,%r4 # long | 122 | llgtr %r4,%r4 # long |
| 123 | llgfr %r5,%r5 # long | 123 | llgfr %r5,%r5 # long |
| 124 | jg sys_ptrace # branch to system call | 124 | jg compat_sys_ptrace # branch to system call |
| 125 | 125 | ||
| 126 | .globl sys32_alarm_wrapper | 126 | .globl sys32_alarm_wrapper |
| 127 | sys32_alarm_wrapper: | 127 | sys32_alarm_wrapper: |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index bdbb3bcd78a5..708cf9cf9a35 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -279,8 +279,6 @@ sysc_do_restart: | |||
| 279 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 279 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
| 280 | 280 | ||
| 281 | sysc_return: | 281 | sysc_return: |
| 282 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 283 | bno BASED(sysc_restore) | ||
| 284 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 282 | tm __TI_flags+3(%r9),_TIF_WORK_SVC |
| 285 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 283 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
| 286 | sysc_restore: | 284 | sysc_restore: |
| @@ -312,6 +310,8 @@ sysc_work_loop: | |||
| 312 | # One of the work bits is on. Find out which one. | 310 | # One of the work bits is on. Find out which one. |
| 313 | # | 311 | # |
| 314 | sysc_work: | 312 | sysc_work: |
| 313 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 314 | bno BASED(sysc_restore) | ||
| 315 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 315 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
| 316 | bo BASED(sysc_mcck_pending) | 316 | bo BASED(sysc_mcck_pending) |
| 317 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 317 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
| @@ -602,12 +602,6 @@ io_no_vtime: | |||
| 602 | la %r2,SP_PTREGS(%r15) # address of register-save area | 602 | la %r2,SP_PTREGS(%r15) # address of register-save area |
| 603 | basr %r14,%r1 # branch to standard irq handler | 603 | basr %r14,%r1 # branch to standard irq handler |
| 604 | io_return: | 604 | io_return: |
| 605 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 606 | #ifdef CONFIG_PREEMPT | ||
| 607 | bno BASED(io_preempt) # no -> check for preemptive scheduling | ||
| 608 | #else | ||
| 609 | bno BASED(io_restore) # no-> skip resched & signal | ||
| 610 | #endif | ||
| 611 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 605 | tm __TI_flags+3(%r9),_TIF_WORK_INT |
| 612 | bnz BASED(io_work) # there is work to do (signals etc.) | 606 | bnz BASED(io_work) # there is work to do (signals etc.) |
| 613 | io_restore: | 607 | io_restore: |
| @@ -629,10 +623,18 @@ io_restore_trace_psw: | |||
| 629 | .long 0, io_restore_trace + 0x80000000 | 623 | .long 0, io_restore_trace + 0x80000000 |
| 630 | #endif | 624 | #endif |
| 631 | 625 | ||
| 632 | #ifdef CONFIG_PREEMPT | 626 | # |
| 633 | io_preempt: | 627 | # switch to kernel stack, then check the TIF bits |
| 628 | # | ||
| 629 | io_work: | ||
| 630 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 631 | #ifndef CONFIG_PREEMPT | ||
| 632 | bno BASED(io_restore) # no-> skip resched & signal | ||
| 633 | #else | ||
| 634 | bnz BASED(io_work_user) # no -> check for preemptive scheduling | ||
| 635 | # check for preemptive scheduling | ||
| 634 | icm %r0,15,__TI_precount(%r9) | 636 | icm %r0,15,__TI_precount(%r9) |
| 635 | bnz BASED(io_restore) | 637 | bnz BASED(io_restore) # preemption disabled |
| 636 | l %r1,SP_R15(%r15) | 638 | l %r1,SP_R15(%r15) |
| 637 | s %r1,BASED(.Lc_spsize) | 639 | s %r1,BASED(.Lc_spsize) |
| 638 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 640 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
| @@ -646,10 +648,7 @@ io_resume_loop: | |||
| 646 | br %r1 # call schedule | 648 | br %r1 # call schedule |
| 647 | #endif | 649 | #endif |
| 648 | 650 | ||
| 649 | # | 651 | io_work_user: |
| 650 | # switch to kernel stack, then check the TIF bits | ||
| 651 | # | ||
| 652 | io_work: | ||
| 653 | l %r1,__LC_KERNEL_STACK | 652 | l %r1,__LC_KERNEL_STACK |
| 654 | s %r1,BASED(.Lc_spsize) | 653 | s %r1,BASED(.Lc_spsize) |
| 655 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 654 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 5a4a7bcd2bba..fee10177dbfc 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -271,8 +271,6 @@ sysc_noemu: | |||
| 271 | stg %r2,SP_R2(%r15) # store return value (change R2 on stack) | 271 | stg %r2,SP_R2(%r15) # store return value (change R2 on stack) |
| 272 | 272 | ||
| 273 | sysc_return: | 273 | sysc_return: |
| 274 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 275 | jno sysc_restore | ||
| 276 | tm __TI_flags+7(%r9),_TIF_WORK_SVC | 274 | tm __TI_flags+7(%r9),_TIF_WORK_SVC |
| 277 | jnz sysc_work # there is work to do (signals etc.) | 275 | jnz sysc_work # there is work to do (signals etc.) |
| 278 | sysc_restore: | 276 | sysc_restore: |
| @@ -304,6 +302,8 @@ sysc_work_loop: | |||
| 304 | # One of the work bits is on. Find out which one. | 302 | # One of the work bits is on. Find out which one. |
| 305 | # | 303 | # |
| 306 | sysc_work: | 304 | sysc_work: |
| 305 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 306 | jno sysc_restore | ||
| 307 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | 307 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING |
| 308 | jo sysc_mcck_pending | 308 | jo sysc_mcck_pending |
| 309 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 309 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
| @@ -585,12 +585,6 @@ io_no_vtime: | |||
| 585 | la %r2,SP_PTREGS(%r15) # address of register-save area | 585 | la %r2,SP_PTREGS(%r15) # address of register-save area |
| 586 | brasl %r14,do_IRQ # call standard irq handler | 586 | brasl %r14,do_IRQ # call standard irq handler |
| 587 | io_return: | 587 | io_return: |
| 588 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 589 | #ifdef CONFIG_PREEMPT | ||
| 590 | jno io_preempt # no -> check for preemptive scheduling | ||
| 591 | #else | ||
| 592 | jno io_restore # no-> skip resched & signal | ||
| 593 | #endif | ||
| 594 | tm __TI_flags+7(%r9),_TIF_WORK_INT | 588 | tm __TI_flags+7(%r9),_TIF_WORK_INT |
| 595 | jnz io_work # there is work to do (signals etc.) | 589 | jnz io_work # there is work to do (signals etc.) |
| 596 | io_restore: | 590 | io_restore: |
| @@ -612,10 +606,41 @@ io_restore_trace_psw: | |||
| 612 | .quad 0, io_restore_trace | 606 | .quad 0, io_restore_trace |
| 613 | #endif | 607 | #endif |
| 614 | 608 | ||
| 615 | #ifdef CONFIG_PREEMPT | 609 | # |
| 616 | io_preempt: | 610 | # There is work todo, we need to check if we return to userspace, then |
| 611 | # check, if we are in SIE, if yes leave it | ||
| 612 | # | ||
| 613 | io_work: | ||
| 614 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
| 615 | #ifndef CONFIG_PREEMPT | ||
| 616 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
| 617 | jnz io_work_user # yes -> no need to check for SIE | ||
| 618 | la %r1, BASED(sie_opcode) # we return to kernel here | ||
| 619 | lg %r2, SP_PSW+8(%r15) | ||
| 620 | clc 0(2,%r1), 0(%r2) # is current instruction = SIE? | ||
| 621 | jne io_restore # no-> return to kernel | ||
| 622 | lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE | ||
| 623 | aghi %r1, 4 | ||
| 624 | stg %r1, SP_PSW+8(%r15) | ||
| 625 | j io_restore # return to kernel | ||
| 626 | #else | ||
| 627 | jno io_restore # no-> skip resched & signal | ||
| 628 | #endif | ||
| 629 | #else | ||
| 630 | jnz io_work_user # yes -> do resched & signal | ||
| 631 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
| 632 | la %r1, BASED(sie_opcode) | ||
| 633 | lg %r2, SP_PSW+8(%r15) | ||
| 634 | clc 0(2,%r1), 0(%r2) # is current instruction = SIE? | ||
| 635 | jne 0f # no -> leave PSW alone | ||
| 636 | lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE | ||
| 637 | aghi %r1, 4 | ||
| 638 | stg %r1, SP_PSW+8(%r15) | ||
| 639 | 0: | ||
| 640 | #endif | ||
| 641 | # check for preemptive scheduling | ||
| 617 | icm %r0,15,__TI_precount(%r9) | 642 | icm %r0,15,__TI_precount(%r9) |
| 618 | jnz io_restore | 643 | jnz io_restore # preemption is disabled |
| 619 | # switch to kernel stack | 644 | # switch to kernel stack |
| 620 | lg %r1,SP_R15(%r15) | 645 | lg %r1,SP_R15(%r15) |
| 621 | aghi %r1,-SP_SIZE | 646 | aghi %r1,-SP_SIZE |
| @@ -629,10 +654,7 @@ io_resume_loop: | |||
| 629 | jg preempt_schedule_irq | 654 | jg preempt_schedule_irq |
| 630 | #endif | 655 | #endif |
| 631 | 656 | ||
| 632 | # | 657 | io_work_user: |
| 633 | # switch to kernel stack, then check TIF bits | ||
| 634 | # | ||
| 635 | io_work: | ||
| 636 | lg %r1,__LC_KERNEL_STACK | 658 | lg %r1,__LC_KERNEL_STACK |
| 637 | aghi %r1,-SP_SIZE | 659 | aghi %r1,-SP_SIZE |
| 638 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 660 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
| @@ -653,6 +675,11 @@ io_work_loop: | |||
| 653 | j io_restore | 675 | j io_restore |
| 654 | io_work_done: | 676 | io_work_done: |
| 655 | 677 | ||
| 678 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
| 679 | sie_opcode: | ||
| 680 | .long 0xb2140000 | ||
| 681 | #endif | ||
| 682 | |||
| 656 | # | 683 | # |
| 657 | # _TIF_MCCK_PENDING is set, call handler | 684 | # _TIF_MCCK_PENDING is set, call handler |
| 658 | # | 685 | # |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 7f4270163744..35827b9bd4d1 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -292,8 +292,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
| 292 | return 0; | 292 | return 0; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static int | 295 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
| 296 | do_ptrace_normal(struct task_struct *child, long request, long addr, long data) | ||
| 297 | { | 296 | { |
| 298 | ptrace_area parea; | 297 | ptrace_area parea; |
| 299 | int copied, ret; | 298 | int copied, ret; |
| @@ -529,35 +528,19 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) | |||
| 529 | return 0; | 528 | return 0; |
| 530 | } | 529 | } |
| 531 | 530 | ||
| 532 | static int | 531 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
| 533 | do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) | 532 | compat_ulong_t caddr, compat_ulong_t cdata) |
| 534 | { | 533 | { |
| 535 | unsigned int tmp; /* 4 bytes !! */ | 534 | unsigned long addr = caddr; |
| 535 | unsigned long data = cdata; | ||
| 536 | ptrace_area_emu31 parea; | 536 | ptrace_area_emu31 parea; |
| 537 | int copied, ret; | 537 | int copied, ret; |
| 538 | 538 | ||
| 539 | switch (request) { | 539 | switch (request) { |
| 540 | case PTRACE_PEEKTEXT: | ||
| 541 | case PTRACE_PEEKDATA: | ||
| 542 | /* read word at location addr. */ | ||
| 543 | copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); | ||
| 544 | if (copied != sizeof(tmp)) | ||
| 545 | return -EIO; | ||
| 546 | return put_user(tmp, (unsigned int __force __user *) data); | ||
| 547 | |||
| 548 | case PTRACE_PEEKUSR: | 540 | case PTRACE_PEEKUSR: |
| 549 | /* read the word at location addr in the USER area. */ | 541 | /* read the word at location addr in the USER area. */ |
| 550 | return peek_user_emu31(child, addr, data); | 542 | return peek_user_emu31(child, addr, data); |
| 551 | 543 | ||
| 552 | case PTRACE_POKETEXT: | ||
| 553 | case PTRACE_POKEDATA: | ||
| 554 | /* write the word at location addr. */ | ||
| 555 | tmp = data; | ||
| 556 | copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1); | ||
| 557 | if (copied != sizeof(tmp)) | ||
| 558 | return -EIO; | ||
| 559 | return 0; | ||
| 560 | |||
| 561 | case PTRACE_POKEUSR: | 544 | case PTRACE_POKEUSR: |
| 562 | /* write the word at location addr in the USER area */ | 545 | /* write the word at location addr in the USER area */ |
| 563 | return poke_user_emu31(child, addr, data); | 546 | return poke_user_emu31(child, addr, data); |
| @@ -587,82 +570,11 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) | |||
| 587 | copied += sizeof(unsigned int); | 570 | copied += sizeof(unsigned int); |
| 588 | } | 571 | } |
| 589 | return 0; | 572 | return 0; |
| 590 | case PTRACE_GETEVENTMSG: | ||
| 591 | return put_user((__u32) child->ptrace_message, | ||
| 592 | (unsigned int __force __user *) data); | ||
| 593 | case PTRACE_GETSIGINFO: | ||
| 594 | if (child->last_siginfo == NULL) | ||
| 595 | return -EINVAL; | ||
| 596 | return copy_siginfo_to_user32((compat_siginfo_t | ||
| 597 | __force __user *) data, | ||
| 598 | child->last_siginfo); | ||
| 599 | case PTRACE_SETSIGINFO: | ||
| 600 | if (child->last_siginfo == NULL) | ||
| 601 | return -EINVAL; | ||
| 602 | return copy_siginfo_from_user32(child->last_siginfo, | ||
| 603 | (compat_siginfo_t | ||
| 604 | __force __user *) data); | ||
| 605 | } | 573 | } |
| 606 | return ptrace_request(child, request, addr, data); | 574 | return compat_ptrace_request(child, request, addr, data); |
| 607 | } | 575 | } |
| 608 | #endif | 576 | #endif |
| 609 | 577 | ||
| 610 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||
| 611 | { | ||
| 612 | switch (request) { | ||
| 613 | case PTRACE_SYSCALL: | ||
| 614 | /* continue and stop at next (return from) syscall */ | ||
| 615 | case PTRACE_CONT: | ||
| 616 | /* restart after signal. */ | ||
| 617 | if (!valid_signal(data)) | ||
| 618 | return -EIO; | ||
| 619 | if (request == PTRACE_SYSCALL) | ||
| 620 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
| 621 | else | ||
| 622 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
| 623 | child->exit_code = data; | ||
| 624 | /* make sure the single step bit is not set. */ | ||
| 625 | user_disable_single_step(child); | ||
| 626 | wake_up_process(child); | ||
| 627 | return 0; | ||
| 628 | |||
| 629 | case PTRACE_KILL: | ||
| 630 | /* | ||
| 631 | * make the child exit. Best I can do is send it a sigkill. | ||
| 632 | * perhaps it should be put in the status that it wants to | ||
| 633 | * exit. | ||
| 634 | */ | ||
| 635 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
| 636 | return 0; | ||
| 637 | child->exit_code = SIGKILL; | ||
| 638 | /* make sure the single step bit is not set. */ | ||
| 639 | user_disable_single_step(child); | ||
| 640 | wake_up_process(child); | ||
| 641 | return 0; | ||
| 642 | |||
| 643 | case PTRACE_SINGLESTEP: | ||
| 644 | /* set the trap flag. */ | ||
| 645 | if (!valid_signal(data)) | ||
| 646 | return -EIO; | ||
| 647 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
| 648 | child->exit_code = data; | ||
| 649 | user_enable_single_step(child); | ||
| 650 | /* give it a chance to run. */ | ||
| 651 | wake_up_process(child); | ||
| 652 | return 0; | ||
| 653 | |||
| 654 | /* Do requests that differ for 31/64 bit */ | ||
| 655 | default: | ||
| 656 | #ifdef CONFIG_COMPAT | ||
| 657 | if (test_thread_flag(TIF_31BIT)) | ||
| 658 | return do_ptrace_emu31(child, request, addr, data); | ||
| 659 | #endif | ||
| 660 | return do_ptrace_normal(child, request, addr, data); | ||
| 661 | } | ||
| 662 | /* Not reached. */ | ||
| 663 | return -EIO; | ||
| 664 | } | ||
| 665 | |||
| 666 | asmlinkage void | 578 | asmlinkage void |
| 667 | syscall_trace(struct pt_regs *regs, int entryexit) | 579 | syscall_trace(struct pt_regs *regs, int entryexit) |
| 668 | { | 580 | { |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 1761b74d639b..e051cad1f1e0 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
| @@ -22,7 +22,6 @@ config KVM | |||
| 22 | select PREEMPT_NOTIFIERS | 22 | select PREEMPT_NOTIFIERS |
| 23 | select ANON_INODES | 23 | select ANON_INODES |
| 24 | select S390_SWITCH_AMODE | 24 | select S390_SWITCH_AMODE |
| 25 | select PREEMPT | ||
| 26 | ---help--- | 25 | ---help--- |
| 27 | Support hosting paravirtualized guest machines using the SIE | 26 | Support hosting paravirtualized guest machines using the SIE |
| 28 | virtualization capability on the mainframe. This should work | 27 | virtualization capability on the mainframe. This should work |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 349581a26103..47a0b642174c 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
| @@ -105,6 +105,9 @@ static intercept_handler_t instruction_handlers[256] = { | |||
| 105 | static int handle_noop(struct kvm_vcpu *vcpu) | 105 | static int handle_noop(struct kvm_vcpu *vcpu) |
| 106 | { | 106 | { |
| 107 | switch (vcpu->arch.sie_block->icptcode) { | 107 | switch (vcpu->arch.sie_block->icptcode) { |
| 108 | case 0x0: | ||
| 109 | vcpu->stat.exit_null++; | ||
| 110 | break; | ||
| 108 | case 0x10: | 111 | case 0x10: |
| 109 | vcpu->stat.exit_external_request++; | 112 | vcpu->stat.exit_external_request++; |
| 110 | break; | 113 | break; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 98d1e73e01f1..0ac36a649eba 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 32 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
| 33 | { "userspace_handled", VCPU_STAT(exit_userspace) }, | 33 | { "userspace_handled", VCPU_STAT(exit_userspace) }, |
| 34 | { "exit_null", VCPU_STAT(exit_null) }, | ||
| 34 | { "exit_validity", VCPU_STAT(exit_validity) }, | 35 | { "exit_validity", VCPU_STAT(exit_validity) }, |
| 35 | { "exit_stop_request", VCPU_STAT(exit_stop_request) }, | 36 | { "exit_stop_request", VCPU_STAT(exit_stop_request) }, |
| 36 | { "exit_external_request", VCPU_STAT(exit_external_request) }, | 37 | { "exit_external_request", VCPU_STAT(exit_external_request) }, |
| @@ -221,10 +222,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
| 221 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; | 222 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; |
| 222 | restore_fp_regs(&vcpu->arch.guest_fpregs); | 223 | restore_fp_regs(&vcpu->arch.guest_fpregs); |
| 223 | restore_access_regs(vcpu->arch.guest_acrs); | 224 | restore_access_regs(vcpu->arch.guest_acrs); |
| 224 | |||
| 225 | if (signal_pending(current)) | ||
| 226 | atomic_set_mask(CPUSTAT_STOP_INT, | ||
| 227 | &vcpu->arch.sie_block->cpuflags); | ||
| 228 | } | 225 | } |
| 229 | 226 | ||
| 230 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 227 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index fb988a48a754..2a7458134544 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile | |||
| @@ -5,3 +5,4 @@ | |||
| 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o |
| 6 | obj-$(CONFIG_CMM) += cmm.o | 6 | obj-$(CONFIG_CMM) += cmm.o |
| 7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
| 8 | obj-$(CONFIG_PAGE_STATES) += page-states.o | ||
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index fa31de6ae97a..29f3a63806b9 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
| @@ -126,6 +126,9 @@ void __init mem_init(void) | |||
| 126 | /* clear the zero-page */ | 126 | /* clear the zero-page */ |
| 127 | memset(empty_zero_page, 0, PAGE_SIZE); | 127 | memset(empty_zero_page, 0, PAGE_SIZE); |
| 128 | 128 | ||
| 129 | /* Setup guest page hinting */ | ||
| 130 | cmma_init(); | ||
| 131 | |||
| 129 | /* this will put all low memory onto the freelists */ | 132 | /* this will put all low memory onto the freelists */ |
| 130 | totalram_pages += free_all_bootmem(); | 133 | totalram_pages += free_all_bootmem(); |
| 131 | 134 | ||
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c new file mode 100644 index 000000000000..fc0ad73ffd90 --- /dev/null +++ b/arch/s390/mm/page-states.c | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /* | ||
| 2 | * arch/s390/mm/page-states.c | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2008 | ||
| 5 | * | ||
| 6 | * Guest page hinting for unused pages. | ||
| 7 | * | ||
| 8 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/mm.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | |||
| 17 | #define ESSA_SET_STABLE 1 | ||
| 18 | #define ESSA_SET_UNUSED 2 | ||
| 19 | |||
| 20 | static int cmma_flag; | ||
| 21 | |||
| 22 | static int __init cmma(char *str) | ||
| 23 | { | ||
| 24 | char *parm; | ||
| 25 | parm = strstrip(str); | ||
| 26 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { | ||
| 27 | cmma_flag = 1; | ||
| 28 | return 1; | ||
| 29 | } | ||
| 30 | cmma_flag = 0; | ||
| 31 | if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0) | ||
| 32 | return 1; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | __setup("cmma=", cmma); | ||
| 37 | |||
| 38 | void __init cmma_init(void) | ||
| 39 | { | ||
| 40 | register unsigned long tmp asm("0") = 0; | ||
| 41 | register int rc asm("1") = -EOPNOTSUPP; | ||
| 42 | |||
| 43 | if (!cmma_flag) | ||
| 44 | return; | ||
| 45 | asm volatile( | ||
| 46 | " .insn rrf,0xb9ab0000,%1,%1,0,0\n" | ||
| 47 | "0: la %0,0\n" | ||
| 48 | "1:\n" | ||
| 49 | EX_TABLE(0b,1b) | ||
| 50 | : "+&d" (rc), "+&d" (tmp)); | ||
| 51 | if (rc) | ||
| 52 | cmma_flag = 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | void arch_free_page(struct page *page, int order) | ||
| 56 | { | ||
| 57 | int i, rc; | ||
| 58 | |||
| 59 | if (!cmma_flag) | ||
| 60 | return; | ||
| 61 | for (i = 0; i < (1 << order); i++) | ||
| 62 | asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" | ||
| 63 | : "=&d" (rc) | ||
| 64 | : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), | ||
| 65 | "i" (ESSA_SET_UNUSED)); | ||
| 66 | } | ||
| 67 | |||
| 68 | void arch_alloc_page(struct page *page, int order) | ||
| 69 | { | ||
| 70 | int i, rc; | ||
| 71 | |||
| 72 | if (!cmma_flag) | ||
| 73 | return; | ||
| 74 | for (i = 0; i < (1 << order); i++) | ||
| 75 | asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" | ||
| 76 | : "=&d" (rc) | ||
| 77 | : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), | ||
| 78 | "i" (ESSA_SET_STABLE)); | ||
| 79 | } | ||
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index c1f2adefad41..5043150019ac 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
| @@ -965,8 +965,7 @@ tty3270_write_room(struct tty_struct *tty) | |||
| 965 | * Insert character into the screen at the current position with the | 965 | * Insert character into the screen at the current position with the |
| 966 | * current color and highlight. This function does NOT do cursor movement. | 966 | * current color and highlight. This function does NOT do cursor movement. |
| 967 | */ | 967 | */ |
| 968 | static int | 968 | static void tty3270_put_character(struct tty3270 *tp, char ch) |
| 969 | tty3270_put_character(struct tty3270 *tp, char ch) | ||
| 970 | { | 969 | { |
| 971 | struct tty3270_line *line; | 970 | struct tty3270_line *line; |
| 972 | struct tty3270_cell *cell; | 971 | struct tty3270_cell *cell; |
| @@ -986,7 +985,6 @@ tty3270_put_character(struct tty3270 *tp, char ch) | |||
| 986 | cell->character = tp->view.ascebc[(unsigned int) ch]; | 985 | cell->character = tp->view.ascebc[(unsigned int) ch]; |
| 987 | cell->highlight = tp->highlight; | 986 | cell->highlight = tp->highlight; |
| 988 | cell->f_color = tp->f_color; | 987 | cell->f_color = tp->f_color; |
| 989 | return 1; | ||
| 990 | } | 988 | } |
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| @@ -1612,16 +1610,15 @@ tty3270_write(struct tty_struct * tty, | |||
| 1612 | /* | 1610 | /* |
| 1613 | * Put single characters to the ttys character buffer | 1611 | * Put single characters to the ttys character buffer |
| 1614 | */ | 1612 | */ |
| 1615 | static void | 1613 | static int tty3270_put_char(struct tty_struct *tty, unsigned char ch) |
| 1616 | tty3270_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 1617 | { | 1614 | { |
| 1618 | struct tty3270 *tp; | 1615 | struct tty3270 *tp; |
| 1619 | 1616 | ||
| 1620 | tp = tty->driver_data; | 1617 | tp = tty->driver_data; |
| 1621 | if (!tp) | 1618 | if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE) |
| 1622 | return; | 1619 | return 0; |
| 1623 | if (tp->char_count < TTY3270_CHAR_BUF_SIZE) | 1620 | tp->char_buf[tp->char_count++] = ch; |
| 1624 | tp->char_buf[tp->char_count++] = ch; | 1621 | return 1; |
| 1625 | } | 1622 | } |
| 1626 | 1623 | ||
| 1627 | /* | 1624 | /* |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 40ef948fcb3a..9c21b8f43f9b 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include <asm/cio.h> | 20 | #include <asm/cio.h> |
| 21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| 22 | #include <asm/cio.h> | ||
| 22 | 23 | ||
| 23 | #include "blacklist.h" | 24 | #include "blacklist.h" |
| 24 | #include "cio.h" | 25 | #include "cio.h" |
| @@ -43,164 +44,169 @@ typedef enum {add, free} range_action; | |||
| 43 | * Function: blacklist_range | 44 | * Function: blacklist_range |
| 44 | * (Un-)blacklist the devices from-to | 45 | * (Un-)blacklist the devices from-to |
| 45 | */ | 46 | */ |
| 46 | static void | 47 | static int blacklist_range(range_action action, unsigned int from_ssid, |
| 47 | blacklist_range (range_action action, unsigned int from, unsigned int to, | 48 | unsigned int to_ssid, unsigned int from, |
| 48 | unsigned int ssid) | 49 | unsigned int to, int msgtrigger) |
| 49 | { | 50 | { |
| 50 | if (!to) | 51 | if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) { |
| 51 | to = from; | 52 | if (msgtrigger) |
| 52 | 53 | printk(KERN_WARNING "cio: Invalid cio_ignore range " | |
| 53 | if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) { | 54 | "0.%x.%04x-0.%x.%04x\n", from_ssid, from, |
| 54 | printk (KERN_WARNING "cio: Invalid blacklist range " | 55 | to_ssid, to); |
| 55 | "0.%x.%04x to 0.%x.%04x, skipping\n", | 56 | return 1; |
| 56 | ssid, from, ssid, to); | ||
| 57 | return; | ||
| 58 | } | 57 | } |
| 59 | for (; from <= to; from++) { | 58 | |
| 59 | while ((from_ssid < to_ssid) || ((from_ssid == to_ssid) && | ||
| 60 | (from <= to))) { | ||
| 60 | if (action == add) | 61 | if (action == add) |
| 61 | set_bit (from, bl_dev[ssid]); | 62 | set_bit(from, bl_dev[from_ssid]); |
| 62 | else | 63 | else |
| 63 | clear_bit (from, bl_dev[ssid]); | 64 | clear_bit(from, bl_dev[from_ssid]); |
| 65 | from++; | ||
| 66 | if (from > __MAX_SUBCHANNEL) { | ||
| 67 | from_ssid++; | ||
| 68 | from = 0; | ||
| 69 | } | ||
| 64 | } | 70 | } |
| 71 | |||
| 72 | return 0; | ||
| 65 | } | 73 | } |
| 66 | 74 | ||
| 67 | /* | 75 | static int pure_hex(char **cp, unsigned int *val, int min_digit, |
| 68 | * Function: blacklist_busid | 76 | int max_digit, int max_val) |
| 69 | * Get devno/busid from given string. | ||
| 70 | * Shamelessly grabbed from dasd_devmap.c. | ||
| 71 | */ | ||
| 72 | static int | ||
| 73 | blacklist_busid(char **str, int *id0, int *ssid, int *devno) | ||
| 74 | { | 77 | { |
| 75 | int val, old_style; | 78 | int diff; |
| 76 | char *sav; | 79 | unsigned int value; |
| 77 | 80 | ||
| 78 | sav = *str; | 81 | diff = 0; |
| 82 | *val = 0; | ||
| 79 | 83 | ||
| 80 | /* check for leading '0x' */ | 84 | while (isxdigit(**cp) && (diff <= max_digit)) { |
| 81 | old_style = 0; | 85 | |
| 82 | if ((*str)[0] == '0' && (*str)[1] == 'x') { | 86 | if (isdigit(**cp)) |
| 83 | *str += 2; | 87 | value = **cp - '0'; |
| 84 | old_style = 1; | 88 | else |
| 85 | } | 89 | value = tolower(**cp) - 'a' + 10; |
| 86 | if (!isxdigit((*str)[0])) /* We require at least one hex digit */ | 90 | *val = *val * 16 + value; |
| 87 | goto confused; | 91 | (*cp)++; |
| 88 | val = simple_strtoul(*str, str, 16); | 92 | diff++; |
| 89 | if (old_style || (*str)[0] != '.') { | ||
| 90 | *id0 = *ssid = 0; | ||
| 91 | if (val < 0 || val > 0xffff) | ||
| 92 | goto confused; | ||
| 93 | *devno = val; | ||
| 94 | if ((*str)[0] != ',' && (*str)[0] != '-' && | ||
| 95 | (*str)[0] != '\n' && (*str)[0] != '\0') | ||
| 96 | goto confused; | ||
| 97 | return 0; | ||
| 98 | } | 93 | } |
| 99 | /* New style x.y.z busid */ | 94 | |
| 100 | if (val < 0 || val > 0xff) | 95 | if ((diff < min_digit) || (diff > max_digit) || (*val > max_val)) |
| 101 | goto confused; | 96 | return 1; |
| 102 | *id0 = val; | 97 | |
| 103 | (*str)++; | ||
| 104 | if (!isxdigit((*str)[0])) /* We require at least one hex digit */ | ||
| 105 | goto confused; | ||
| 106 | val = simple_strtoul(*str, str, 16); | ||
| 107 | if (val < 0 || val > 0xff || (*str)++[0] != '.') | ||
| 108 | goto confused; | ||
| 109 | *ssid = val; | ||
| 110 | if (!isxdigit((*str)[0])) /* We require at least one hex digit */ | ||
| 111 | goto confused; | ||
| 112 | val = simple_strtoul(*str, str, 16); | ||
| 113 | if (val < 0 || val > 0xffff) | ||
| 114 | goto confused; | ||
| 115 | *devno = val; | ||
| 116 | if ((*str)[0] != ',' && (*str)[0] != '-' && | ||
| 117 | (*str)[0] != '\n' && (*str)[0] != '\0') | ||
| 118 | goto confused; | ||
| 119 | return 0; | 98 | return 0; |
| 120 | confused: | ||
| 121 | strsep(str, ",\n"); | ||
| 122 | printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav); | ||
| 123 | return 1; | ||
| 124 | } | 99 | } |
| 125 | 100 | ||
| 126 | static int | 101 | static int parse_busid(char *str, int *cssid, int *ssid, int *devno, |
| 127 | blacklist_parse_parameters (char *str, range_action action) | 102 | int msgtrigger) |
| 128 | { | 103 | { |
| 129 | int from, to, from_id0, to_id0, from_ssid, to_ssid; | 104 | char *str_work; |
| 130 | 105 | int val, rc, ret; | |
| 131 | while (*str != 0 && *str != '\n') { | 106 | |
| 132 | range_action ra = action; | 107 | rc = 1; |
| 133 | while(*str == ',') | 108 | |
| 134 | str++; | 109 | if (*str == '\0') |
| 135 | if (*str == '!') { | 110 | goto out; |
| 136 | ra = !action; | 111 | |
| 137 | ++str; | 112 | /* old style */ |
| 113 | str_work = str; | ||
| 114 | val = simple_strtoul(str, &str_work, 16); | ||
| 115 | |||
| 116 | if (*str_work == '\0') { | ||
| 117 | if (val <= __MAX_SUBCHANNEL) { | ||
| 118 | *devno = val; | ||
| 119 | *ssid = 0; | ||
| 120 | *cssid = 0; | ||
| 121 | rc = 0; | ||
| 138 | } | 122 | } |
| 123 | goto out; | ||
| 124 | } | ||
| 139 | 125 | ||
| 140 | /* | 126 | /* new style */ |
| 141 | * Since we have to parse the proc commands and the | 127 | str_work = str; |
| 142 | * kernel arguments we have to check four cases | 128 | ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID); |
| 143 | */ | 129 | if (ret || (str_work[0] != '.')) |
| 144 | if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 || | 130 | goto out; |
| 145 | strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) { | 131 | str_work++; |
| 146 | int j; | 132 | ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID); |
| 147 | 133 | if (ret || (str_work[0] != '.')) | |
| 148 | str += 3; | 134 | goto out; |
| 149 | for (j=0; j <= __MAX_SSID; j++) | 135 | str_work++; |
| 150 | blacklist_range(ra, 0, __MAX_SUBCHANNEL, j); | 136 | ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL); |
| 151 | } else { | 137 | if (ret || (str_work[0] != '\0')) |
| 152 | int rc; | 138 | goto out; |
| 139 | |||
| 140 | rc = 0; | ||
| 141 | out: | ||
| 142 | if (rc && msgtrigger) | ||
| 143 | printk(KERN_WARNING "cio: Invalid cio_ignore device '%s'\n", | ||
| 144 | str); | ||
| 145 | |||
| 146 | return rc; | ||
| 147 | } | ||
| 153 | 148 | ||
| 154 | rc = blacklist_busid(&str, &from_id0, | 149 | static int blacklist_parse_parameters(char *str, range_action action, |
| 155 | &from_ssid, &from); | 150 | int msgtrigger) |
| 156 | if (rc) | 151 | { |
| 157 | continue; | 152 | int from_cssid, to_cssid, from_ssid, to_ssid, from, to; |
| 158 | to = from; | 153 | int rc, totalrc; |
| 159 | to_id0 = from_id0; | 154 | char *parm; |
| 160 | to_ssid = from_ssid; | 155 | range_action ra; |
| 161 | if (*str == '-') { | 156 | |
| 162 | str++; | 157 | totalrc = 0; |
| 163 | rc = blacklist_busid(&str, &to_id0, | 158 | |
| 164 | &to_ssid, &to); | 159 | while ((parm = strsep(&str, ","))) { |
| 165 | if (rc) | 160 | rc = 0; |
| 166 | continue; | 161 | ra = action; |
| 167 | } | 162 | if (*parm == '!') { |
| 168 | if (*str == '-') { | 163 | if (ra == add) |
| 169 | printk(KERN_WARNING "cio: invalid cio_ignore " | 164 | ra = free; |
| 170 | "parameter '%s'\n", | 165 | else |
| 171 | strsep(&str, ",\n")); | 166 | ra = add; |
| 172 | continue; | 167 | parm++; |
| 173 | } | 168 | } |
| 174 | if ((from_id0 != to_id0) || | 169 | if (strcmp(parm, "all") == 0) { |
| 175 | (from_ssid != to_ssid)) { | 170 | from_cssid = 0; |
| 176 | printk(KERN_WARNING "cio: invalid cio_ignore " | 171 | from_ssid = 0; |
| 177 | "range %x.%x.%04x-%x.%x.%04x\n", | 172 | from = 0; |
| 178 | from_id0, from_ssid, from, | 173 | to_cssid = __MAX_CSSID; |
| 179 | to_id0, to_ssid, to); | 174 | to_ssid = __MAX_SSID; |
| 180 | continue; | 175 | to = __MAX_SUBCHANNEL; |
| 176 | } else { | ||
| 177 | rc = parse_busid(strsep(&parm, "-"), &from_cssid, | ||
| 178 | &from_ssid, &from, msgtrigger); | ||
| 179 | if (!rc) { | ||
| 180 | if (parm != NULL) | ||
| 181 | rc = parse_busid(parm, &to_cssid, | ||
| 182 | &to_ssid, &to, | ||
| 183 | msgtrigger); | ||
| 184 | else { | ||
| 185 | to_cssid = from_cssid; | ||
| 186 | to_ssid = from_ssid; | ||
| 187 | to = from; | ||
| 188 | } | ||
| 181 | } | 189 | } |
| 182 | blacklist_range (ra, from, to, to_ssid); | ||
| 183 | } | 190 | } |
| 191 | if (!rc) { | ||
| 192 | rc = blacklist_range(ra, from_ssid, to_ssid, from, to, | ||
| 193 | msgtrigger); | ||
| 194 | if (rc) | ||
| 195 | totalrc = 1; | ||
| 196 | } else | ||
| 197 | totalrc = 1; | ||
| 184 | } | 198 | } |
| 185 | return 1; | 199 | |
| 200 | return totalrc; | ||
| 186 | } | 201 | } |
| 187 | 202 | ||
| 188 | /* Parsing the commandline for blacklist parameters, e.g. to blacklist | ||
| 189 | * bus ids 0.0.1234, 0.0.1235 and 0.0.1236, you could use any of: | ||
| 190 | * - cio_ignore=1234-1236 | ||
| 191 | * - cio_ignore=0x1234-0x1235,1236 | ||
| 192 | * - cio_ignore=0x1234,1235-1236 | ||
| 193 | * - cio_ignore=1236 cio_ignore=1234-0x1236 | ||
| 194 | * - cio_ignore=1234 cio_ignore=1236 cio_ignore=0x1235 | ||
| 195 | * - cio_ignore=0.0.1234-0.0.1236 | ||
| 196 | * - cio_ignore=0.0.1234,0x1235,1236 | ||
| 197 | * - ... | ||
| 198 | */ | ||
| 199 | static int __init | 203 | static int __init |
| 200 | blacklist_setup (char *str) | 204 | blacklist_setup (char *str) |
| 201 | { | 205 | { |
| 202 | CIO_MSG_EVENT(6, "Reading blacklist parameters\n"); | 206 | CIO_MSG_EVENT(6, "Reading blacklist parameters\n"); |
| 203 | return blacklist_parse_parameters (str, add); | 207 | if (blacklist_parse_parameters(str, add, 1)) |
| 208 | return 0; | ||
| 209 | return 1; | ||
| 204 | } | 210 | } |
| 205 | 211 | ||
| 206 | __setup ("cio_ignore=", blacklist_setup); | 212 | __setup ("cio_ignore=", blacklist_setup); |
| @@ -224,27 +230,23 @@ is_blacklisted (int ssid, int devno) | |||
| 224 | * Function: blacklist_parse_proc_parameters | 230 | * Function: blacklist_parse_proc_parameters |
| 225 | * parse the stuff which is piped to /proc/cio_ignore | 231 | * parse the stuff which is piped to /proc/cio_ignore |
| 226 | */ | 232 | */ |
| 227 | static void | 233 | static int blacklist_parse_proc_parameters(char *buf) |
| 228 | blacklist_parse_proc_parameters (char *buf) | ||
| 229 | { | 234 | { |
| 230 | if (strncmp (buf, "free ", 5) == 0) { | 235 | int rc; |
| 231 | blacklist_parse_parameters (buf + 5, free); | 236 | char *parm; |
| 232 | } else if (strncmp (buf, "add ", 4) == 0) { | 237 | |
| 233 | /* | 238 | parm = strsep(&buf, " "); |
| 234 | * We don't need to check for known devices since | 239 | |
| 235 | * css_probe_device will handle this correctly. | 240 | if (strcmp("free", parm) == 0) |
| 236 | */ | 241 | rc = blacklist_parse_parameters(buf, free, 0); |
| 237 | blacklist_parse_parameters (buf + 4, add); | 242 | else if (strcmp("add", parm) == 0) |
| 238 | } else { | 243 | rc = blacklist_parse_parameters(buf, add, 0); |
| 239 | printk (KERN_WARNING "cio: cio_ignore: Parse error; \n" | 244 | else |
| 240 | KERN_WARNING "try using 'free all|<devno-range>," | 245 | return 1; |
| 241 | "<devno-range>,...'\n" | ||
| 242 | KERN_WARNING "or 'add <devno-range>," | ||
| 243 | "<devno-range>,...'\n"); | ||
| 244 | return; | ||
| 245 | } | ||
| 246 | 246 | ||
| 247 | css_schedule_reprobe(); | 247 | css_schedule_reprobe(); |
| 248 | |||
| 249 | return rc; | ||
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | /* Iterator struct for all devices. */ | 252 | /* Iterator struct for all devices. */ |
| @@ -328,6 +330,8 @@ cio_ignore_write(struct file *file, const char __user *user_buf, | |||
| 328 | size_t user_len, loff_t *offset) | 330 | size_t user_len, loff_t *offset) |
| 329 | { | 331 | { |
| 330 | char *buf; | 332 | char *buf; |
| 333 | size_t i; | ||
| 334 | ssize_t rc, ret; | ||
| 331 | 335 | ||
| 332 | if (*offset) | 336 | if (*offset) |
| 333 | return -EINVAL; | 337 | return -EINVAL; |
| @@ -336,16 +340,27 @@ cio_ignore_write(struct file *file, const char __user *user_buf, | |||
| 336 | buf = vmalloc (user_len + 1); /* maybe better use the stack? */ | 340 | buf = vmalloc (user_len + 1); /* maybe better use the stack? */ |
| 337 | if (buf == NULL) | 341 | if (buf == NULL) |
| 338 | return -ENOMEM; | 342 | return -ENOMEM; |
| 343 | memset(buf, 0, user_len + 1); | ||
| 344 | |||
| 339 | if (strncpy_from_user (buf, user_buf, user_len) < 0) { | 345 | if (strncpy_from_user (buf, user_buf, user_len) < 0) { |
| 340 | vfree (buf); | 346 | rc = -EFAULT; |
| 341 | return -EFAULT; | 347 | goto out_free; |
| 342 | } | 348 | } |
| 343 | buf[user_len] = '\0'; | ||
| 344 | 349 | ||
| 345 | blacklist_parse_proc_parameters (buf); | 350 | i = user_len - 1; |
| 351 | while ((i >= 0) && (isspace(buf[i]) || (buf[i] == 0))) { | ||
| 352 | buf[i] = '\0'; | ||
| 353 | i--; | ||
| 354 | } | ||
| 355 | ret = blacklist_parse_proc_parameters(buf); | ||
| 356 | if (ret) | ||
| 357 | rc = -EINVAL; | ||
| 358 | else | ||
| 359 | rc = user_len; | ||
| 346 | 360 | ||
| 361 | out_free: | ||
| 347 | vfree (buf); | 362 | vfree (buf); |
| 348 | return user_len; | 363 | return rc; |
| 349 | } | 364 | } |
| 350 | 365 | ||
| 351 | static const struct seq_operations cio_ignore_proc_seq_ops = { | 366 | static const struct seq_operations cio_ignore_proc_seq_ops = { |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 08a578161306..82c6a2d45128 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
| @@ -39,23 +39,6 @@ debug_info_t *cio_debug_msg_id; | |||
| 39 | debug_info_t *cio_debug_trace_id; | 39 | debug_info_t *cio_debug_trace_id; |
| 40 | debug_info_t *cio_debug_crw_id; | 40 | debug_info_t *cio_debug_crw_id; |
| 41 | 41 | ||
| 42 | int cio_show_msg; | ||
| 43 | |||
| 44 | static int __init | ||
| 45 | cio_setup (char *parm) | ||
| 46 | { | ||
| 47 | if (!strcmp (parm, "yes")) | ||
| 48 | cio_show_msg = 1; | ||
| 49 | else if (!strcmp (parm, "no")) | ||
| 50 | cio_show_msg = 0; | ||
| 51 | else | ||
| 52 | printk(KERN_ERR "cio: cio_setup: " | ||
| 53 | "invalid cio_msg parameter '%s'", parm); | ||
| 54 | return 1; | ||
| 55 | } | ||
| 56 | |||
| 57 | __setup ("cio_msg=", cio_setup); | ||
| 58 | |||
| 59 | /* | 42 | /* |
| 60 | * Function: cio_debug_init | 43 | * Function: cio_debug_init |
| 61 | * Initializes three debug logs for common I/O: | 44 | * Initializes three debug logs for common I/O: |
| @@ -166,7 +149,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) | |||
| 166 | 149 | ||
| 167 | stsch (sch->schid, &sch->schib); | 150 | stsch (sch->schid, &sch->schib); |
| 168 | 151 | ||
| 169 | CIO_MSG_EVENT(0, "cio_start: 'not oper' status for " | 152 | CIO_MSG_EVENT(2, "cio_start: 'not oper' status for " |
| 170 | "subchannel 0.%x.%04x!\n", sch->schid.ssid, | 153 | "subchannel 0.%x.%04x!\n", sch->schid.ssid, |
| 171 | sch->schid.sch_no); | 154 | sch->schid.sch_no); |
| 172 | sprintf(dbf_text, "no%s", sch->dev.bus_id); | 155 | sprintf(dbf_text, "no%s", sch->dev.bus_id); |
| @@ -567,10 +550,9 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
| 567 | * ... just being curious we check for non I/O subchannels | 550 | * ... just being curious we check for non I/O subchannels |
| 568 | */ | 551 | */ |
| 569 | if (sch->st != 0) { | 552 | if (sch->st != 0) { |
| 570 | CIO_DEBUG(KERN_INFO, 0, | 553 | CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports " |
| 571 | "Subchannel 0.%x.%04x reports " | 554 | "non-I/O subchannel type %04X\n", |
| 572 | "non-I/O subchannel type %04X\n", | 555 | sch->schid.ssid, sch->schid.sch_no, sch->st); |
| 573 | sch->schid.ssid, sch->schid.sch_no, sch->st); | ||
| 574 | /* We stop here for non-io subchannels. */ | 556 | /* We stop here for non-io subchannels. */ |
| 575 | err = sch->st; | 557 | err = sch->st; |
| 576 | goto out; | 558 | goto out; |
| @@ -588,7 +570,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
| 588 | * This device must not be known to Linux. So we simply | 570 | * This device must not be known to Linux. So we simply |
| 589 | * say that there is no device and return ENODEV. | 571 | * say that there is no device and return ENODEV. |
| 590 | */ | 572 | */ |
| 591 | CIO_MSG_EVENT(4, "Blacklisted device detected " | 573 | CIO_MSG_EVENT(6, "Blacklisted device detected " |
| 592 | "at devno %04X, subchannel set %x\n", | 574 | "at devno %04X, subchannel set %x\n", |
| 593 | sch->schib.pmcw.dev, sch->schid.ssid); | 575 | sch->schib.pmcw.dev, sch->schid.ssid); |
| 594 | err = -ENODEV; | 576 | err = -ENODEV; |
| @@ -601,12 +583,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
| 601 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | 583 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
| 602 | sch->isc = 3; | 584 | sch->isc = 3; |
| 603 | 585 | ||
| 604 | CIO_DEBUG(KERN_INFO, 0, | 586 | CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " |
| 605 | "Detected device %04x on subchannel 0.%x.%04X" | 587 | "- PIM = %02X, PAM = %02X, POM = %02X\n", |
| 606 | " - PIM = %02X, PAM = %02X, POM = %02X\n", | 588 | sch->schib.pmcw.dev, sch->schid.ssid, |
| 607 | sch->schib.pmcw.dev, sch->schid.ssid, | 589 | sch->schid.sch_no, sch->schib.pmcw.pim, |
| 608 | sch->schid.sch_no, sch->schib.pmcw.pim, | 590 | sch->schib.pmcw.pam, sch->schib.pmcw.pom); |
| 609 | sch->schib.pmcw.pam, sch->schib.pmcw.pom); | ||
| 610 | 591 | ||
| 611 | /* | 592 | /* |
| 612 | * We now have to initially ... | 593 | * We now have to initially ... |
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 3c75412904dc..6e933aebe013 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h | |||
| @@ -118,6 +118,4 @@ extern void *cio_get_console_priv(void); | |||
| 118 | #define cio_get_console_priv() NULL | 118 | #define cio_get_console_priv() NULL |
| 119 | #endif | 119 | #endif |
| 120 | 120 | ||
| 121 | extern int cio_show_msg; | ||
| 122 | |||
| 123 | #endif | 121 | #endif |
diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index d7429ef6c666..e64e8278c42e 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h | |||
| @@ -31,10 +31,4 @@ static inline void CIO_HEX_EVENT(int level, void *data, int length) | |||
| 31 | } | 31 | } |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | #define CIO_DEBUG(printk_level, event_level, msg...) do { \ | ||
| 35 | if (cio_show_msg) \ | ||
| 36 | printk(printk_level "cio: " msg); \ | ||
| 37 | CIO_MSG_EVENT(event_level, msg); \ | ||
| 38 | } while (0) | ||
| 39 | |||
| 40 | #endif | 34 | #endif |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 595e327d2f76..a76956512b2d 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
| @@ -570,7 +570,7 @@ static void reprobe_all(struct work_struct *unused) | |||
| 570 | { | 570 | { |
| 571 | int ret; | 571 | int ret; |
| 572 | 572 | ||
| 573 | CIO_MSG_EVENT(2, "reprobe start\n"); | 573 | CIO_MSG_EVENT(4, "reprobe start\n"); |
| 574 | 574 | ||
| 575 | need_reprobe = 0; | 575 | need_reprobe = 0; |
| 576 | /* Make sure initial subchannel scan is done. */ | 576 | /* Make sure initial subchannel scan is done. */ |
| @@ -578,7 +578,7 @@ static void reprobe_all(struct work_struct *unused) | |||
| 578 | atomic_read(&ccw_device_init_count) == 0); | 578 | atomic_read(&ccw_device_init_count) == 0); |
| 579 | ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); | 579 | ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); |
| 580 | 580 | ||
| 581 | CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, | 581 | CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, |
| 582 | need_reprobe); | 582 | need_reprobe); |
| 583 | } | 583 | } |
| 584 | 584 | ||
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index abfd601d237a..e22813db74a2 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -341,7 +341,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) | |||
| 341 | rc = device_schedule_callback(&cdev->dev, | 341 | rc = device_schedule_callback(&cdev->dev, |
| 342 | ccw_device_remove_orphan_cb); | 342 | ccw_device_remove_orphan_cb); |
| 343 | if (rc) | 343 | if (rc) |
| 344 | CIO_MSG_EVENT(2, "Couldn't unregister orphan " | 344 | CIO_MSG_EVENT(0, "Couldn't unregister orphan " |
| 345 | "0.%x.%04x\n", | 345 | "0.%x.%04x\n", |
| 346 | cdev->private->dev_id.ssid, | 346 | cdev->private->dev_id.ssid, |
| 347 | cdev->private->dev_id.devno); | 347 | cdev->private->dev_id.devno); |
| @@ -351,7 +351,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) | |||
| 351 | rc = device_schedule_callback(cdev->dev.parent, | 351 | rc = device_schedule_callback(cdev->dev.parent, |
| 352 | ccw_device_remove_sch_cb); | 352 | ccw_device_remove_sch_cb); |
| 353 | if (rc) | 353 | if (rc) |
| 354 | CIO_MSG_EVENT(2, "Couldn't unregister disconnected device " | 354 | CIO_MSG_EVENT(0, "Couldn't unregister disconnected device " |
| 355 | "0.%x.%04x\n", | 355 | "0.%x.%04x\n", |
| 356 | cdev->private->dev_id.ssid, | 356 | cdev->private->dev_id.ssid, |
| 357 | cdev->private->dev_id.devno); | 357 | cdev->private->dev_id.devno); |
| @@ -397,7 +397,7 @@ int ccw_device_set_offline(struct ccw_device *cdev) | |||
| 397 | if (ret == 0) | 397 | if (ret == 0) |
| 398 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); | 398 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); |
| 399 | else { | 399 | else { |
| 400 | CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " | 400 | CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " |
| 401 | "device 0.%x.%04x\n", | 401 | "device 0.%x.%04x\n", |
| 402 | ret, cdev->private->dev_id.ssid, | 402 | ret, cdev->private->dev_id.ssid, |
| 403 | cdev->private->dev_id.devno); | 403 | cdev->private->dev_id.devno); |
| @@ -433,7 +433,7 @@ int ccw_device_set_online(struct ccw_device *cdev) | |||
| 433 | if (ret == 0) | 433 | if (ret == 0) |
| 434 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); | 434 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); |
| 435 | else { | 435 | else { |
| 436 | CIO_MSG_EVENT(2, "ccw_device_online returned %d, " | 436 | CIO_MSG_EVENT(0, "ccw_device_online returned %d, " |
| 437 | "device 0.%x.%04x\n", | 437 | "device 0.%x.%04x\n", |
| 438 | ret, cdev->private->dev_id.ssid, | 438 | ret, cdev->private->dev_id.ssid, |
| 439 | cdev->private->dev_id.devno); | 439 | cdev->private->dev_id.devno); |
| @@ -451,7 +451,7 @@ int ccw_device_set_online(struct ccw_device *cdev) | |||
| 451 | if (ret == 0) | 451 | if (ret == 0) |
| 452 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); | 452 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); |
| 453 | else | 453 | else |
| 454 | CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " | 454 | CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " |
| 455 | "device 0.%x.%04x\n", | 455 | "device 0.%x.%04x\n", |
| 456 | ret, cdev->private->dev_id.ssid, | 456 | ret, cdev->private->dev_id.ssid, |
| 457 | cdev->private->dev_id.devno); | 457 | cdev->private->dev_id.devno); |
| @@ -803,7 +803,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch, | |||
| 803 | other_sch = to_subchannel(get_device(cdev->dev.parent)); | 803 | other_sch = to_subchannel(get_device(cdev->dev.parent)); |
| 804 | ret = device_move(&cdev->dev, &sch->dev); | 804 | ret = device_move(&cdev->dev, &sch->dev); |
| 805 | if (ret) { | 805 | if (ret) { |
| 806 | CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed " | 806 | CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " |
| 807 | "(ret=%d)!\n", cdev->private->dev_id.ssid, | 807 | "(ret=%d)!\n", cdev->private->dev_id.ssid, |
| 808 | cdev->private->dev_id.devno, ret); | 808 | cdev->private->dev_id.devno, ret); |
| 809 | put_device(&other_sch->dev); | 809 | put_device(&other_sch->dev); |
| @@ -933,7 +933,7 @@ io_subchannel_register(struct work_struct *work) | |||
| 933 | ret = device_reprobe(&cdev->dev); | 933 | ret = device_reprobe(&cdev->dev); |
| 934 | if (ret) | 934 | if (ret) |
| 935 | /* We can't do much here. */ | 935 | /* We can't do much here. */ |
| 936 | CIO_MSG_EVENT(2, "device_reprobe() returned" | 936 | CIO_MSG_EVENT(0, "device_reprobe() returned" |
| 937 | " %d for 0.%x.%04x\n", ret, | 937 | " %d for 0.%x.%04x\n", ret, |
| 938 | cdev->private->dev_id.ssid, | 938 | cdev->private->dev_id.ssid, |
| 939 | cdev->private->dev_id.devno); | 939 | cdev->private->dev_id.devno); |
| @@ -1086,7 +1086,7 @@ static void ccw_device_move_to_sch(struct work_struct *work) | |||
| 1086 | rc = device_move(&cdev->dev, &sch->dev); | 1086 | rc = device_move(&cdev->dev, &sch->dev); |
| 1087 | mutex_unlock(&sch->reg_mutex); | 1087 | mutex_unlock(&sch->reg_mutex); |
| 1088 | if (rc) { | 1088 | if (rc) { |
| 1089 | CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel " | 1089 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " |
| 1090 | "0.%x.%04x failed (ret=%d)!\n", | 1090 | "0.%x.%04x failed (ret=%d)!\n", |
| 1091 | cdev->private->dev_id.ssid, | 1091 | cdev->private->dev_id.ssid, |
| 1092 | cdev->private->dev_id.devno, sch->schid.ssid, | 1092 | cdev->private->dev_id.devno, sch->schid.ssid, |
| @@ -1446,8 +1446,7 @@ ccw_device_remove (struct device *dev) | |||
| 1446 | wait_event(cdev->private->wait_q, | 1446 | wait_event(cdev->private->wait_q, |
| 1447 | dev_fsm_final_state(cdev)); | 1447 | dev_fsm_final_state(cdev)); |
| 1448 | else | 1448 | else |
| 1449 | //FIXME: we can't fail! | 1449 | CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " |
| 1450 | CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " | ||
| 1451 | "device 0.%x.%04x\n", | 1450 | "device 0.%x.%04x\n", |
| 1452 | ret, cdev->private->dev_id.ssid, | 1451 | ret, cdev->private->dev_id.ssid, |
| 1453 | cdev->private->dev_id.devno); | 1452 | cdev->private->dev_id.devno); |
| @@ -1524,7 +1523,7 @@ static int recovery_check(struct device *dev, void *data) | |||
| 1524 | spin_lock_irq(cdev->ccwlock); | 1523 | spin_lock_irq(cdev->ccwlock); |
| 1525 | switch (cdev->private->state) { | 1524 | switch (cdev->private->state) { |
| 1526 | case DEV_STATE_DISCONNECTED: | 1525 | case DEV_STATE_DISCONNECTED: |
| 1527 | CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", | 1526 | CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n", |
| 1528 | cdev->private->dev_id.ssid, | 1527 | cdev->private->dev_id.ssid, |
| 1529 | cdev->private->dev_id.devno); | 1528 | cdev->private->dev_id.devno); |
| 1530 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); | 1529 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); |
| @@ -1554,7 +1553,7 @@ static void recovery_work_func(struct work_struct *unused) | |||
| 1554 | } | 1553 | } |
| 1555 | spin_unlock_irq(&recovery_lock); | 1554 | spin_unlock_irq(&recovery_lock); |
| 1556 | } else | 1555 | } else |
| 1557 | CIO_MSG_EVENT(2, "recovery: end\n"); | 1556 | CIO_MSG_EVENT(4, "recovery: end\n"); |
| 1558 | } | 1557 | } |
| 1559 | 1558 | ||
| 1560 | static DECLARE_WORK(recovery_work, recovery_work_func); | 1559 | static DECLARE_WORK(recovery_work, recovery_work_func); |
| @@ -1572,7 +1571,7 @@ void ccw_device_schedule_recovery(void) | |||
| 1572 | { | 1571 | { |
| 1573 | unsigned long flags; | 1572 | unsigned long flags; |
| 1574 | 1573 | ||
| 1575 | CIO_MSG_EVENT(2, "recovery: schedule\n"); | 1574 | CIO_MSG_EVENT(4, "recovery: schedule\n"); |
| 1576 | spin_lock_irqsave(&recovery_lock, flags); | 1575 | spin_lock_irqsave(&recovery_lock, flags); |
| 1577 | if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { | 1576 | if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { |
| 1578 | recovery_phase = 0; | 1577 | recovery_phase = 0; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 99403b0a97a7..e268d5a77c12 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
| @@ -322,10 +322,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 322 | same_dev = 0; /* Keep the compiler quiet... */ | 322 | same_dev = 0; /* Keep the compiler quiet... */ |
| 323 | switch (state) { | 323 | switch (state) { |
| 324 | case DEV_STATE_NOT_OPER: | 324 | case DEV_STATE_NOT_OPER: |
| 325 | CIO_DEBUG(KERN_WARNING, 2, | 325 | CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " |
| 326 | "SenseID : unknown device %04x on subchannel " | 326 | "subchannel 0.%x.%04x\n", |
| 327 | "0.%x.%04x\n", cdev->private->dev_id.devno, | 327 | cdev->private->dev_id.devno, |
| 328 | sch->schid.ssid, sch->schid.sch_no); | 328 | sch->schid.ssid, sch->schid.sch_no); |
| 329 | break; | 329 | break; |
| 330 | case DEV_STATE_OFFLINE: | 330 | case DEV_STATE_OFFLINE: |
| 331 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { | 331 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { |
| @@ -348,20 +348,19 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
| 348 | return; | 348 | return; |
| 349 | } | 349 | } |
| 350 | /* Issue device info message. */ | 350 | /* Issue device info message. */ |
| 351 | CIO_DEBUG(KERN_INFO, 2, | 351 | CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: " |
| 352 | "SenseID : device 0.%x.%04x reports: " | 352 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " |
| 353 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " | 353 | "%04X/%02X\n", |
| 354 | "%04X/%02X\n", | 354 | cdev->private->dev_id.ssid, |
| 355 | cdev->private->dev_id.ssid, | 355 | cdev->private->dev_id.devno, |
| 356 | cdev->private->dev_id.devno, | 356 | cdev->id.cu_type, cdev->id.cu_model, |
| 357 | cdev->id.cu_type, cdev->id.cu_model, | 357 | cdev->id.dev_type, cdev->id.dev_model); |
| 358 | cdev->id.dev_type, cdev->id.dev_model); | ||
| 359 | break; | 358 | break; |
| 360 | case DEV_STATE_BOXED: | 359 | case DEV_STATE_BOXED: |
| 361 | CIO_DEBUG(KERN_WARNING, 2, | 360 | CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " |
| 362 | "SenseID : boxed device %04x on subchannel " | 361 | " subchannel 0.%x.%04x\n", |
| 363 | "0.%x.%04x\n", cdev->private->dev_id.devno, | 362 | cdev->private->dev_id.devno, |
| 364 | sch->schid.ssid, sch->schid.sch_no); | 363 | sch->schid.ssid, sch->schid.sch_no); |
| 365 | break; | 364 | break; |
| 366 | } | 365 | } |
| 367 | cdev->private->state = state; | 366 | cdev->private->state = state; |
| @@ -443,9 +442,8 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
| 443 | 442 | ||
| 444 | 443 | ||
| 445 | if (state == DEV_STATE_BOXED) | 444 | if (state == DEV_STATE_BOXED) |
| 446 | CIO_DEBUG(KERN_WARNING, 2, | 445 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", |
| 447 | "Boxed device %04x on subchannel %04x\n", | 446 | cdev->private->dev_id.devno, sch->schid.sch_no); |
| 448 | cdev->private->dev_id.devno, sch->schid.sch_no); | ||
| 449 | 447 | ||
| 450 | if (cdev->private->flags.donotify) { | 448 | if (cdev->private->flags.donotify) { |
| 451 | cdev->private->flags.donotify = 0; | 449 | cdev->private->flags.donotify = 0; |
| @@ -900,7 +898,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 900 | /* Basic sense hasn't started. Try again. */ | 898 | /* Basic sense hasn't started. Try again. */ |
| 901 | ccw_device_do_sense(cdev, irb); | 899 | ccw_device_do_sense(cdev, irb); |
| 902 | else { | 900 | else { |
| 903 | CIO_MSG_EVENT(2, "Huh? 0.%x.%04x: unsolicited " | 901 | CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited " |
| 904 | "interrupt during w4sense...\n", | 902 | "interrupt during w4sense...\n", |
| 905 | cdev->private->dev_id.ssid, | 903 | cdev->private->dev_id.ssid, |
| 906 | cdev->private->dev_id.devno); | 904 | cdev->private->dev_id.devno); |
| @@ -1169,8 +1167,10 @@ ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 1169 | static void | 1167 | static void |
| 1170 | ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event) | 1168 | ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event) |
| 1171 | { | 1169 | { |
| 1172 | CIO_MSG_EVENT(0, "dev_jumptable[%i][%i] == NULL\n", | 1170 | CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device " |
| 1173 | cdev->private->state, dev_event); | 1171 | "0.%x.%04x\n", cdev->private->state, dev_event, |
| 1172 | cdev->private->dev_id.ssid, | ||
| 1173 | cdev->private->dev_id.devno); | ||
| 1174 | BUG(); | 1174 | BUG(); |
| 1175 | } | 1175 | } |
| 1176 | 1176 | ||
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index dc4d87f77f6c..cba7020517ed 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
| @@ -214,7 +214,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
| 214 | * sense id information. So, for intervention required, | 214 | * sense id information. So, for intervention required, |
| 215 | * we use the "whack it until it talks" strategy... | 215 | * we use the "whack it until it talks" strategy... |
| 216 | */ | 216 | */ |
| 217 | CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " | 217 | CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel " |
| 218 | "0.%x.%04x reports cmd reject\n", | 218 | "0.%x.%04x reports cmd reject\n", |
| 219 | cdev->private->dev_id.devno, sch->schid.ssid, | 219 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 220 | sch->schid.sch_no); | 220 | sch->schid.sch_no); |
| @@ -239,7 +239,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
| 239 | 239 | ||
| 240 | lpm = to_io_private(sch)->orb.lpm; | 240 | lpm = to_io_private(sch)->orb.lpm; |
| 241 | if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) | 241 | if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) |
| 242 | CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " | 242 | CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x " |
| 243 | "on subchannel 0.%x.%04x is " | 243 | "on subchannel 0.%x.%04x is " |
| 244 | "'not operational'\n", lpm, | 244 | "'not operational'\n", lpm, |
| 245 | cdev->private->dev_id.devno, | 245 | cdev->private->dev_id.devno, |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index c52449a1f9fc..ba559053402e 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
| @@ -79,7 +79,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) | |||
| 79 | /* ret is 0, -EBUSY, -EACCES or -ENODEV */ | 79 | /* ret is 0, -EBUSY, -EACCES or -ENODEV */ |
| 80 | if (ret != -EACCES) | 80 | if (ret != -EACCES) |
| 81 | return ret; | 81 | return ret; |
| 82 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " | 82 | CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel " |
| 83 | "0.%x.%04x, lpm %02X, became 'not " | 83 | "0.%x.%04x, lpm %02X, became 'not " |
| 84 | "operational'\n", | 84 | "operational'\n", |
| 85 | cdev->private->dev_id.devno, | 85 | cdev->private->dev_id.devno, |
| @@ -159,7 +159,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
| 159 | u8 lpm; | 159 | u8 lpm; |
| 160 | 160 | ||
| 161 | lpm = to_io_private(sch)->orb.lpm; | 161 | lpm = to_io_private(sch)->orb.lpm; |
| 162 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," | 162 | CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x," |
| 163 | " lpm %02X, became 'not operational'\n", | 163 | " lpm %02X, became 'not operational'\n", |
| 164 | cdev->private->dev_id.devno, sch->schid.ssid, | 164 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 165 | sch->schid.sch_no, lpm); | 165 | sch->schid.sch_no, lpm); |
| @@ -275,7 +275,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) | |||
| 275 | return ret; | 275 | return ret; |
| 276 | } | 276 | } |
| 277 | /* PGID command failed on this path. */ | 277 | /* PGID command failed on this path. */ |
| 278 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " | 278 | CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel " |
| 279 | "0.%x.%04x, lpm %02X, became 'not operational'\n", | 279 | "0.%x.%04x, lpm %02X, became 'not operational'\n", |
| 280 | cdev->private->dev_id.devno, sch->schid.ssid, | 280 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 281 | sch->schid.sch_no, cdev->private->imask); | 281 | sch->schid.sch_no, cdev->private->imask); |
| @@ -317,7 +317,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) | |||
| 317 | return ret; | 317 | return ret; |
| 318 | } | 318 | } |
| 319 | /* nop command failed on this path. */ | 319 | /* nop command failed on this path. */ |
| 320 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " | 320 | CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel " |
| 321 | "0.%x.%04x, lpm %02X, became 'not operational'\n", | 321 | "0.%x.%04x, lpm %02X, became 'not operational'\n", |
| 322 | cdev->private->dev_id.devno, sch->schid.ssid, | 322 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 323 | sch->schid.sch_no, cdev->private->imask); | 323 | sch->schid.sch_no, cdev->private->imask); |
| @@ -362,7 +362,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
| 362 | return -EAGAIN; | 362 | return -EAGAIN; |
| 363 | } | 363 | } |
| 364 | if (irb->scsw.cc == 3) { | 364 | if (irb->scsw.cc == 3) { |
| 365 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," | 365 | CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x," |
| 366 | " lpm %02X, became 'not operational'\n", | 366 | " lpm %02X, became 'not operational'\n", |
| 367 | cdev->private->dev_id.devno, sch->schid.ssid, | 367 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 368 | sch->schid.sch_no, cdev->private->imask); | 368 | sch->schid.sch_no, cdev->private->imask); |
| @@ -391,7 +391,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) | |||
| 391 | return -ETIME; | 391 | return -ETIME; |
| 392 | } | 392 | } |
| 393 | if (irb->scsw.cc == 3) { | 393 | if (irb->scsw.cc == 3) { |
| 394 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," | 394 | CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x," |
| 395 | " lpm %02X, became 'not operational'\n", | 395 | " lpm %02X, became 'not operational'\n", |
| 396 | cdev->private->dev_id.devno, sch->schid.ssid, | 396 | cdev->private->dev_id.devno, sch->schid.ssid, |
| 397 | sch->schid.sch_no, cdev->private->imask); | 397 | sch->schid.sch_no, cdev->private->imask); |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 4d4b54277c43..5080f343ad74 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
| @@ -48,10 +48,11 @@ s390_collect_crw_info(void *param) | |||
| 48 | int ccode; | 48 | int ccode; |
| 49 | struct semaphore *sem; | 49 | struct semaphore *sem; |
| 50 | unsigned int chain; | 50 | unsigned int chain; |
| 51 | int ignore; | ||
| 51 | 52 | ||
| 52 | sem = (struct semaphore *)param; | 53 | sem = (struct semaphore *)param; |
| 53 | repeat: | 54 | repeat: |
| 54 | down_interruptible(sem); | 55 | ignore = down_interruptible(sem); |
| 55 | chain = 0; | 56 | chain = 0; |
| 56 | while (1) { | 57 | while (1) { |
| 57 | if (unlikely(chain > 1)) { | 58 | if (unlikely(chain > 1)) { |
diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index f8204a4f2e02..18cbd8a39796 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h | |||
| @@ -104,6 +104,7 @@ struct sie_block { | |||
| 104 | 104 | ||
| 105 | struct kvm_vcpu_stat { | 105 | struct kvm_vcpu_stat { |
| 106 | u32 exit_userspace; | 106 | u32 exit_userspace; |
| 107 | u32 exit_null; | ||
| 107 | u32 exit_external_request; | 108 | u32 exit_external_request; |
| 108 | u32 exit_external_interrupt; | 109 | u32 exit_external_interrupt; |
| 109 | u32 exit_stop_request; | 110 | u32 exit_stop_request; |
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index f0f4579eac13..12fd9c4f0f15 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h | |||
| @@ -125,6 +125,17 @@ page_get_storage_key(unsigned long addr) | |||
| 125 | return skey; | 125 | return skey; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | #ifdef CONFIG_PAGE_STATES | ||
| 129 | |||
| 130 | struct page; | ||
| 131 | void arch_free_page(struct page *page, int order); | ||
| 132 | void arch_alloc_page(struct page *page, int order); | ||
| 133 | |||
| 134 | #define HAVE_ARCH_FREE_PAGE | ||
| 135 | #define HAVE_ARCH_ALLOC_PAGE | ||
| 136 | |||
| 137 | #endif | ||
| 138 | |||
| 128 | #endif /* !__ASSEMBLY__ */ | 139 | #endif /* !__ASSEMBLY__ */ |
| 129 | 140 | ||
| 130 | /* to align the pointer to the (next) page boundary */ | 141 | /* to align the pointer to the (next) page boundary */ |
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 441d7c260857..d7d4e2eb3e6f 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h | |||
| @@ -471,6 +471,8 @@ struct task_struct; | |||
| 471 | extern void user_enable_single_step(struct task_struct *); | 471 | extern void user_enable_single_step(struct task_struct *); |
| 472 | extern void user_disable_single_step(struct task_struct *); | 472 | extern void user_disable_single_step(struct task_struct *); |
| 473 | 473 | ||
| 474 | #define __ARCH_WANT_COMPAT_SYS_PTRACE | ||
| 475 | |||
| 474 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | 476 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) |
| 475 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | 477 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) |
| 476 | #define regs_return_value(regs)((regs)->gprs[2]) | 478 | #define regs_return_value(regs)((regs)->gprs[2]) |
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index c819ae25a842..e0d4500d5f95 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h | |||
| @@ -116,6 +116,12 @@ extern void pfault_fini(void); | |||
| 116 | #define pfault_fini() do { } while (0) | 116 | #define pfault_fini() do { } while (0) |
| 117 | #endif /* CONFIG_PFAULT */ | 117 | #endif /* CONFIG_PFAULT */ |
| 118 | 118 | ||
| 119 | #ifdef CONFIG_PAGE_STATES | ||
| 120 | extern void cmma_init(void); | ||
| 121 | #else | ||
| 122 | static inline void cmma_init(void) { } | ||
| 123 | #endif | ||
| 124 | |||
| 119 | #define finish_arch_switch(prev) do { \ | 125 | #define finish_arch_switch(prev) do { \ |
| 120 | set_fs(current->thread.mm_segment); \ | 126 | set_fs(current->thread.mm_segment); \ |
| 121 | account_vtime(prev); \ | 127 | account_vtime(prev); \ |
