~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to arch/s390/mm/fault.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <asm/asm-offsets.h>
35
35
#include <asm/system.h>
36
36
#include <asm/pgtable.h>
37
 
#include <asm/s390_ext.h>
 
37
#include <asm/irq.h>
38
38
#include <asm/mmu_context.h>
39
39
#include <asm/compat.h>
40
40
#include "../kernel/entry.h"
225
225
        force_sig_info(SIGBUS, &si, tsk);
226
226
}
227
227
 
228
 
#ifdef CONFIG_S390_EXEC_PROTECT
229
 
static noinline int signal_return(struct pt_regs *regs, long int_code,
230
 
                                  unsigned long trans_exc_code)
231
 
{
232
 
        u16 instruction;
233
 
        int rc;
234
 
 
235
 
        rc = __get_user(instruction, (u16 __user *) regs->psw.addr);
236
 
 
237
 
        if (!rc && instruction == 0x0a77) {
238
 
                clear_tsk_thread_flag(current, TIF_PER_TRAP);
239
 
                if (is_compat_task())
240
 
                        sys32_sigreturn();
241
 
                else
242
 
                        sys_sigreturn();
243
 
        } else if (!rc && instruction == 0x0aad) {
244
 
                clear_tsk_thread_flag(current, TIF_PER_TRAP);
245
 
                if (is_compat_task())
246
 
                        sys32_rt_sigreturn();
247
 
                else
248
 
                        sys_rt_sigreturn();
249
 
        } else
250
 
                do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
251
 
        return 0;
252
 
}
253
 
#endif /* CONFIG_S390_EXEC_PROTECT */
254
 
 
255
228
static noinline void do_fault_error(struct pt_regs *regs, long int_code,
256
229
                                    unsigned long trans_exc_code, int fault)
257
230
{
259
232
 
260
233
        switch (fault) {
261
234
        case VM_FAULT_BADACCESS:
262
 
#ifdef CONFIG_S390_EXEC_PROTECT
263
 
                if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
264
 
                    (trans_exc_code & 3) == 0) {
265
 
                        signal_return(regs, int_code, trans_exc_code);
266
 
                        break;
267
 
                }
268
 
#endif /* CONFIG_S390_EXEC_PROTECT */
269
235
        case VM_FAULT_BADMAP:
270
236
                /* Bad memory access. Check if it is kernel or user space. */
271
237
                if (regs->psw.mask & PSW_MASK_PSTATE) {
279
245
                do_no_context(regs, int_code, trans_exc_code);
280
246
                break;
281
247
        default: /* fault & VM_FAULT_ERROR */
282
 
                if (fault & VM_FAULT_OOM)
283
 
                        pagefault_out_of_memory();
284
 
                else if (fault & VM_FAULT_SIGBUS) {
 
248
                if (fault & VM_FAULT_OOM) {
 
249
                        if (!(regs->psw.mask & PSW_MASK_PSTATE))
 
250
                                do_no_context(regs, int_code, trans_exc_code);
 
251
                        else
 
252
                                pagefault_out_of_memory();
 
253
                } else if (fault & VM_FAULT_SIGBUS) {
285
254
                        /* Kernel mode? Handle exceptions or die */
286
255
                        if (!(regs->psw.mask & PSW_MASK_PSTATE))
287
256
                                do_no_context(regs, int_code, trans_exc_code);
311
280
        struct mm_struct *mm;
312
281
        struct vm_area_struct *vma;
313
282
        unsigned long address;
314
 
        int fault, write;
 
283
        unsigned int flags;
 
284
        int fault;
315
285
 
316
286
        if (notify_page_fault(regs))
317
287
                return 0;
330
300
 
331
301
        address = trans_exc_code & __FAIL_ADDR_MASK;
332
302
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
303
        flags = FAULT_FLAG_ALLOW_RETRY;
 
304
        if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
 
305
                flags |= FAULT_FLAG_WRITE;
 
306
retry:
333
307
        down_read(&mm->mmap_sem);
334
308
 
335
309
        fault = VM_FAULT_BADMAP;
359
333
         * make sure we exit gracefully rather than endlessly redo
360
334
         * the fault.
361
335
         */
362
 
        write = (access == VM_WRITE ||
363
 
                 (trans_exc_code & store_indication) == 0x400) ?
364
 
                FAULT_FLAG_WRITE : 0;
365
 
        fault = handle_mm_fault(mm, vma, address, write);
 
336
        fault = handle_mm_fault(mm, vma, address, flags);
366
337
        if (unlikely(fault & VM_FAULT_ERROR))
367
338
                goto out_up;
368
339
 
369
 
        if (fault & VM_FAULT_MAJOR) {
370
 
                tsk->maj_flt++;
371
 
                perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
372
 
                                     regs, address);
373
 
        } else {
374
 
                tsk->min_flt++;
375
 
                perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
376
 
                                     regs, address);
 
340
        /*
 
341
         * Major/minor page fault accounting is only done on the
 
342
         * initial attempt. If we go through a retry, it is extremely
 
343
         * likely that the page will be found in page cache at that point.
 
344
         */
 
345
        if (flags & FAULT_FLAG_ALLOW_RETRY) {
 
346
                if (fault & VM_FAULT_MAJOR) {
 
347
                        tsk->maj_flt++;
 
348
                        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 
349
                                      regs, address);
 
350
                } else {
 
351
                        tsk->min_flt++;
 
352
                        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 
353
                                      regs, address);
 
354
                }
 
355
                if (fault & VM_FAULT_RETRY) {
 
356
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 
357
                         * of starvation. */
 
358
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
 
359
                        goto retry;
 
360
                }
377
361
        }
378
362
        /*
379
363
         * The instruction that caused the program check will
414
398
        int access, fault;
415
399
 
416
400
        access = VM_READ | VM_EXEC | VM_WRITE;
417
 
#ifdef CONFIG_S390_EXEC_PROTECT
418
 
        if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
419
 
            (trans_exc_code & 3) == 0)
420
 
                access = VM_EXEC;
421
 
#endif
422
401
        fault = do_exception(regs, access, trans_exc_code);
423
402
        if (unlikely(fault))
424
403
                do_fault_error(regs, pgm_int_code & 255, trans_exc_code, fault);
468
447
        access = write ? VM_WRITE : VM_READ;
469
448
        fault = do_exception(&regs, access, uaddr | 2);
470
449
        if (unlikely(fault)) {
471
 
                if (fault & VM_FAULT_OOM) {
472
 
                        pagefault_out_of_memory();
473
 
                        fault = 0;
474
 
                } else if (fault & VM_FAULT_SIGBUS)
 
450
                if (fault & VM_FAULT_OOM)
 
451
                        return -EFAULT;
 
452
                else if (fault & VM_FAULT_SIGBUS)
475
453
                        do_sigbus(&regs, pgm_int_code, uaddr);
476
454
        }
477
455
        return fault ? -EFAULT : 0;
491
469
 
492
470
__setup("nopfault", nopfault);
493
471
 
494
 
typedef struct {
495
 
        __u16 refdiagc;
496
 
        __u16 reffcode;
497
 
        __u16 refdwlen;
498
 
        __u16 refversn;
499
 
        __u64 refgaddr;
500
 
        __u64 refselmk;
501
 
        __u64 refcmpmk;
502
 
        __u64 reserved;
503
 
} __attribute__ ((packed, aligned(8))) pfault_refbk_t;
 
472
struct pfault_refbk {
 
473
        u16 refdiagc;
 
474
        u16 reffcode;
 
475
        u16 refdwlen;
 
476
        u16 refversn;
 
477
        u64 refgaddr;
 
478
        u64 refselmk;
 
479
        u64 refcmpmk;
 
480
        u64 reserved;
 
481
} __attribute__ ((packed, aligned(8)));
504
482
 
505
483
int pfault_init(void)
506
484
{
507
 
        pfault_refbk_t refbk =
508
 
                { 0x258, 0, 5, 2, __LC_CURRENT, 1ULL << 48, 1ULL << 48,
509
 
                  __PF_RES_FIELD };
 
485
        struct pfault_refbk refbk = {
 
486
                .refdiagc = 0x258,
 
487
                .reffcode = 0,
 
488
                .refdwlen = 5,
 
489
                .refversn = 2,
 
490
                .refgaddr = __LC_CURRENT_PID,
 
491
                .refselmk = 1ULL << 48,
 
492
                .refcmpmk = 1ULL << 48,
 
493
                .reserved = __PF_RES_FIELD };
510
494
        int rc;
511
495
 
512
496
        if (!MACHINE_IS_VM || pfault_disable)
518
502
                "2:\n"
519
503
                EX_TABLE(0b,1b)
520
504
                : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc");
521
 
        __ctl_set_bit(0, 9);
522
505
        return rc;
523
506
}
524
507
 
525
508
void pfault_fini(void)
526
509
{
527
 
        pfault_refbk_t refbk =
528
 
        { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL };
 
510
        struct pfault_refbk refbk = {
 
511
                .refdiagc = 0x258,
 
512
                .reffcode = 1,
 
513
                .refdwlen = 5,
 
514
                .refversn = 2,
 
515
        };
529
516
 
530
517
        if (!MACHINE_IS_VM || pfault_disable)
531
518
                return;
532
 
        __ctl_clear_bit(0,9);
533
519
        asm volatile(
534
520
                "       diag    %0,0,0x258\n"
535
521
                "0:\n"
537
523
                : : "a" (&refbk), "m" (refbk) : "cc");
538
524
}
539
525
 
 
526
static DEFINE_SPINLOCK(pfault_lock);
 
527
static LIST_HEAD(pfault_list);
 
528
 
540
529
static void pfault_interrupt(unsigned int ext_int_code,
541
530
                             unsigned int param32, unsigned long param64)
542
531
{
543
532
        struct task_struct *tsk;
544
533
        __u16 subcode;
 
534
        pid_t pid;
545
535
 
546
536
        /*
547
537
         * Get the external interruption subcode & pfault
553
543
        if ((subcode & 0xff00) != __SUBCODE_MASK)
554
544
                return;
555
545
        kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
556
 
 
557
 
        /*
558
 
         * Get the token (= address of the task structure of the affected task).
559
 
         */
560
 
#ifdef CONFIG_64BIT
561
 
        tsk = (struct task_struct *) param64;
562
 
#else
563
 
        tsk = (struct task_struct *) param32;
564
 
#endif
565
 
 
 
546
        if (subcode & 0x0080) {
 
547
                /* Get the token (= pid of the affected task). */
 
548
                pid = sizeof(void *) == 4 ? param32 : param64;
 
549
                rcu_read_lock();
 
550
                tsk = find_task_by_pid_ns(pid, &init_pid_ns);
 
551
                if (tsk)
 
552
                        get_task_struct(tsk);
 
553
                rcu_read_unlock();
 
554
                if (!tsk)
 
555
                        return;
 
556
        } else {
 
557
                tsk = current;
 
558
        }
 
559
        spin_lock(&pfault_lock);
566
560
        if (subcode & 0x0080) {
567
561
                /* signal bit is set -> a page has been swapped in by VM */
568
 
                if (xchg(&tsk->thread.pfault_wait, -1) != 0) {
 
562
                if (tsk->thread.pfault_wait == 1) {
569
563
                        /* Initial interrupt was faster than the completion
570
564
                         * interrupt. pfault_wait is valid. Set pfault_wait
571
565
                         * back to zero and wake up the process. This can
572
566
                         * safely be done because the task is still sleeping
573
567
                         * and can't produce new pfaults. */
574
568
                        tsk->thread.pfault_wait = 0;
 
569
                        list_del(&tsk->thread.list);
575
570
                        wake_up_process(tsk);
576
 
                        put_task_struct(tsk);
 
571
                } else {
 
572
                        /* Completion interrupt was faster than initial
 
573
                         * interrupt. Set pfault_wait to -1 so the initial
 
574
                         * interrupt doesn't put the task to sleep. */
 
575
                        tsk->thread.pfault_wait = -1;
577
576
                }
 
577
                put_task_struct(tsk);
578
578
        } else {
579
579
                /* signal bit not set -> a real page is missing. */
580
 
                get_task_struct(tsk);
581
 
                set_task_state(tsk, TASK_UNINTERRUPTIBLE);
582
 
                if (xchg(&tsk->thread.pfault_wait, 1) != 0) {
 
580
                if (tsk->thread.pfault_wait == -1) {
583
581
                        /* Completion interrupt was faster than the initial
584
 
                         * interrupt (swapped in a -1 for pfault_wait). Set
585
 
                         * pfault_wait back to zero and exit. This can be
586
 
                         * done safely because tsk is running in kernel 
587
 
                         * mode and can't produce new pfaults. */
 
582
                         * interrupt (pfault_wait == -1). Set pfault_wait
 
583
                         * back to zero and exit. */
588
584
                        tsk->thread.pfault_wait = 0;
589
 
                        set_task_state(tsk, TASK_RUNNING);
590
 
                        put_task_struct(tsk);
591
 
                } else
 
585
                } else {
 
586
                        /* Initial interrupt arrived before completion
 
587
                         * interrupt. Let the task sleep. */
 
588
                        tsk->thread.pfault_wait = 1;
 
589
                        list_add(&tsk->thread.list, &pfault_list);
 
590
                        set_task_state(tsk, TASK_UNINTERRUPTIBLE);
592
591
                        set_tsk_need_resched(tsk);
593
 
        }
 
592
                }
 
593
        }
 
594
        spin_unlock(&pfault_lock);
 
595
}
 
596
 
 
597
static int __cpuinit pfault_cpu_notify(struct notifier_block *self,
 
598
                                       unsigned long action, void *hcpu)
 
599
{
 
600
        struct thread_struct *thread, *next;
 
601
        struct task_struct *tsk;
 
602
 
 
603
        switch (action) {
 
604
        case CPU_DEAD:
 
605
        case CPU_DEAD_FROZEN:
 
606
                spin_lock_irq(&pfault_lock);
 
607
                list_for_each_entry_safe(thread, next, &pfault_list, list) {
 
608
                        thread->pfault_wait = 0;
 
609
                        list_del(&thread->list);
 
610
                        tsk = container_of(thread, struct task_struct, thread);
 
611
                        wake_up_process(tsk);
 
612
                }
 
613
                spin_unlock_irq(&pfault_lock);
 
614
                break;
 
615
        default:
 
616
                break;
 
617
        }
 
618
        return NOTIFY_OK;
594
619
}
595
620
 
596
621
static int __init pfault_irq_init(void)
599
624
 
600
625
        if (!MACHINE_IS_VM)
601
626
                return 0;
602
 
        /*
603
 
         * Try to get pfault pseudo page faults going.
604
 
         */
605
627
        rc = register_external_interrupt(0x2603, pfault_interrupt);
606
 
        if (rc) {
607
 
                pfault_disable = 1;
608
 
                return rc;
609
 
        }
610
 
        if (pfault_init() == 0)
611
 
                return 0;
 
628
        if (rc)
 
629
                goto out_extint;
 
630
        rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP;
 
631
        if (rc)
 
632
                goto out_pfault;
 
633
        service_subclass_irq_register();
 
634
        hotcpu_notifier(pfault_cpu_notify, 0);
 
635
        return 0;
612
636
 
613
 
        /* Tough luck, no pfault. */
614
 
        pfault_disable = 1;
 
637
out_pfault:
615
638
        unregister_external_interrupt(0x2603, pfault_interrupt);
616
 
        return 0;
 
639
out_extint:
 
640
        pfault_disable = 1;
 
641
        return rc;
617
642
}
618
643
early_initcall(pfault_irq_init);
619
644
 
620
 
#endif
 
645
#endif /* CONFIG_PFAULT */