~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to target-s390x/helper.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-25 22:31:43 UTC
  • mfrom: (1.8.5)
  • Revision ID: package-import@ubuntu.com-20140225223143-odhqxfc60wxrjl15
Tags: 2.0.0~rc1+dfsg-0ubuntu1
* Merge 2.0.0-rc1
* debian/rules: consolidate ppc filter entries.
* Move qemu-system-arch64 into qemu-system-arm
* debian/patches/define-trusty-machine-type.patch: define a trusty machine
  type, currently the same as pc-i440fx-2.0, to put is in a better position
  to enable live migrations from trusty onward.  (LP: #1294823)
* debian/control: build-dep on libfdt >= 1.4.0  (LP: #1295072)
* Merge latest upstream git to commit dc9528f
* Debian/rules:
  - remove -enable-uname-release=2.6.32
  - don't make the aarch64 target Ubuntu-specific.
* Remove patches which are now upstream:
  - fix-smb-security-share.patch
  - slirp-smb-redirect-port-445-too.patch 
  - linux-user-Implement-sendmmsg-syscall.patch (better version is upstream)
  - signal-added-a-wrapper-for-sigprocmask-function.patch
  - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
  - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch
  - ubuntu/ppc-force-cpu-threads-count-to-be-power-of-2.patch
* add link for /usr/share/qemu/bios-256k.bin
* Remove all linaro patches.
* Remove all arm64/ patches.  Many but not all are upstream.
* Remove CVE-2013-4377.patch which is upstream.
* debian/control-in: don't make qemu-system-aarch64 ubuntu-specific

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
 
86
86
void s390_cpu_do_interrupt(CPUState *cs)
87
87
{
 
88
    cs->exception_index = -1;
 
89
}
 
90
 
 
91
int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 
92
                              int rw, int mmu_idx)
 
93
{
88
94
    S390CPU *cpu = S390_CPU(cs);
89
 
    CPUS390XState *env = &cpu->env;
90
 
 
91
 
    env->exception_index = -1;
92
 
}
93
 
 
94
 
int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
95
 
                               int rw, int mmu_idx)
96
 
{
97
 
    env->exception_index = EXCP_PGM;
98
 
    env->int_pgm_code = PGM_ADDRESSING;
 
95
 
 
96
    cs->exception_index = EXCP_PGM;
 
97
    cpu->env.int_pgm_code = PGM_ADDRESSING;
99
98
    /* On real machines this value is dropped into LowMem.  Since this
100
99
       is userland, simply put this someplace that cpu_loop can find it.  */
101
 
    env->__excp_addr = address;
 
100
    cpu->env.__excp_addr = address;
102
101
    return 1;
103
102
}
104
103
 
108
107
static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
109
108
                                  uint32_t ilen)
110
109
{
111
 
    env->exception_index = EXCP_PGM;
 
110
    CPUState *cs = CPU(s390_env_get_cpu(env));
 
111
 
 
112
    cs->exception_index = EXCP_PGM;
112
113
    env->int_pgm_code = code;
113
114
    env->int_pgm_ilen = ilen;
114
115
}
115
116
 
116
117
static int trans_bits(CPUS390XState *env, uint64_t mode)
117
118
{
 
119
    S390CPU *cpu = s390_env_get_cpu(env);
118
120
    int bits = 0;
119
121
 
120
122
    switch (mode) {
128
130
        bits = 3;
129
131
        break;
130
132
    default:
131
 
        cpu_abort(env, "unknown asc mode\n");
 
133
        cpu_abort(CPU(cpu), "unknown asc mode\n");
132
134
        break;
133
135
    }
134
136
 
138
140
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
139
141
                               uint64_t mode)
140
142
{
 
143
    CPUState *cs = CPU(s390_env_get_cpu(env));
141
144
    int ilen = ILEN_LATER_INC;
142
145
    int bits = trans_bits(env, mode) | 4;
143
146
 
144
147
    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
145
148
 
146
 
    stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
 
149
    stq_phys(cs->as,
 
150
             env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
147
151
    trigger_pgm_exception(env, PGM_PROTECTION, ilen);
148
152
}
149
153
 
150
154
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
151
155
                               uint32_t type, uint64_t asc, int rw)
152
156
{
 
157
    CPUState *cs = CPU(s390_env_get_cpu(env));
153
158
    int ilen = ILEN_LATER;
154
159
    int bits = trans_bits(env, asc);
155
160
 
160
165
 
161
166
    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
162
167
 
163
 
    stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
 
168
    stq_phys(cs->as,
 
169
             env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
164
170
    trigger_pgm_exception(env, type, ilen);
165
171
}
166
172
 
168
174
                              uint64_t asc, uint64_t asce, int level,
169
175
                              target_ulong *raddr, int *flags, int rw)
170
176
{
 
177
    CPUState *cs = CPU(s390_env_get_cpu(env));
171
178
    uint64_t offs = 0;
172
179
    uint64_t origin;
173
180
    uint64_t new_asce;
218
225
    /* XXX region protection flags */
219
226
    /* *flags &= ~PAGE_WRITE */
220
227
 
221
 
    new_asce = ldq_phys(origin + offs);
 
228
    new_asce = ldq_phys(cs->as, origin + offs);
222
229
    PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
223
230
                __func__, origin, offs, new_asce);
224
231
 
374
381
    return r;
375
382
}
376
383
 
377
 
int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
378
 
                               int rw, int mmu_idx)
 
384
int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr,
 
385
                              int rw, int mmu_idx)
379
386
{
 
387
    S390CPU *cpu = S390_CPU(cs);
 
388
    CPUS390XState *env = &cpu->env;
380
389
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
381
390
    target_ulong vaddr, raddr;
382
391
    int prot;
383
392
 
384
 
    DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
 
393
    DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
385
394
            __func__, orig_vaddr, rw, mmu_idx);
386
395
 
387
396
    orig_vaddr &= TARGET_PAGE_MASK;
408
417
    DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __func__,
409
418
            (uint64_t)vaddr, (uint64_t)raddr, prot);
410
419
 
411
 
    tlb_set_page(env, orig_vaddr, raddr, prot,
 
420
    tlb_set_page(cs, orig_vaddr, raddr, prot,
412
421
                 mmu_idx, TARGET_PAGE_SIZE);
413
422
 
414
423
    return 0;
420
429
    CPUS390XState *env = &cpu->env;
421
430
    target_ulong raddr;
422
431
    int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
423
 
    int old_exc = env->exception_index;
 
432
    int old_exc = cs->exception_index;
424
433
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
425
434
 
426
435
    /* 31-Bit mode */
429
438
    }
430
439
 
431
440
    mmu_translate(env, vaddr, 2, asc, &raddr, &prot);
432
 
    env->exception_index = old_exc;
 
441
    cs->exception_index = old_exc;
433
442
 
434
443
    return raddr;
435
444
}
447
456
            }
448
457
        }
449
458
        cs->halted = 1;
450
 
        env->exception_index = EXCP_HLT;
 
459
        cs->exception_index = EXCP_HLT;
451
460
    }
452
461
 
453
462
    env->psw.addr = addr;
471
480
 
472
481
static LowCore *cpu_map_lowcore(CPUS390XState *env)
473
482
{
 
483
    S390CPU *cpu = s390_env_get_cpu(env);
474
484
    LowCore *lowcore;
475
485
    hwaddr len = sizeof(LowCore);
476
486
 
477
487
    lowcore = cpu_physical_memory_map(env->psa, &len, 1);
478
488
 
479
489
    if (len < sizeof(LowCore)) {
480
 
        cpu_abort(env, "Could not map lowcore\n");
 
490
        cpu_abort(CPU(cpu), "Could not map lowcore\n");
481
491
    }
482
492
 
483
493
    return lowcore;
575
585
 
576
586
static void do_ext_interrupt(CPUS390XState *env)
577
587
{
 
588
    S390CPU *cpu = s390_env_get_cpu(env);
578
589
    uint64_t mask, addr;
579
590
    LowCore *lowcore;
580
591
    ExtQueue *q;
581
592
 
582
593
    if (!(env->psw.mask & PSW_MASK_EXT)) {
583
 
        cpu_abort(env, "Ext int w/o ext mask\n");
 
594
        cpu_abort(CPU(cpu), "Ext int w/o ext mask\n");
584
595
    }
585
596
 
586
597
    if (env->ext_index < 0 || env->ext_index > MAX_EXT_QUEUE) {
587
 
        cpu_abort(env, "Ext queue overrun: %d\n", env->ext_index);
 
598
        cpu_abort(CPU(cpu), "Ext queue overrun: %d\n", env->ext_index);
588
599
    }
589
600
 
590
601
    q = &env->ext_queue[env->ext_index];
614
625
 
615
626
static void do_io_interrupt(CPUS390XState *env)
616
627
{
 
628
    S390CPU *cpu = s390_env_get_cpu(env);
617
629
    LowCore *lowcore;
618
630
    IOIntQueue *q;
619
631
    uint8_t isc;
621
633
    int found = 0;
622
634
 
623
635
    if (!(env->psw.mask & PSW_MASK_IO)) {
624
 
        cpu_abort(env, "I/O int w/o I/O mask\n");
 
636
        cpu_abort(CPU(cpu), "I/O int w/o I/O mask\n");
625
637
    }
626
638
 
627
639
    for (isc = 0; isc < ARRAY_SIZE(env->io_index); isc++) {
631
643
            continue;
632
644
        }
633
645
        if (env->io_index[isc] > MAX_IO_QUEUE) {
634
 
            cpu_abort(env, "I/O queue overrun for isc %d: %d\n",
 
646
            cpu_abort(CPU(cpu), "I/O queue overrun for isc %d: %d\n",
635
647
                      isc, env->io_index[isc]);
636
648
        }
637
649
 
678
690
 
679
691
static void do_mchk_interrupt(CPUS390XState *env)
680
692
{
 
693
    S390CPU *cpu = s390_env_get_cpu(env);
681
694
    uint64_t mask, addr;
682
695
    LowCore *lowcore;
683
696
    MchkQueue *q;
684
697
    int i;
685
698
 
686
699
    if (!(env->psw.mask & PSW_MASK_MCHECK)) {
687
 
        cpu_abort(env, "Machine check w/o mchk mask\n");
 
700
        cpu_abort(CPU(cpu), "Machine check w/o mchk mask\n");
688
701
    }
689
702
 
690
703
    if (env->mchk_index < 0 || env->mchk_index > MAX_MCHK_QUEUE) {
691
 
        cpu_abort(env, "Mchk queue overrun: %d\n", env->mchk_index);
 
704
        cpu_abort(CPU(cpu), "Mchk queue overrun: %d\n", env->mchk_index);
692
705
    }
693
706
 
694
707
    q = &env->mchk_queue[env->mchk_index];
695
708
 
696
709
    if (q->type != 1) {
697
710
        /* Don't know how to handle this... */
698
 
        cpu_abort(env, "Unknown machine check type %d\n", q->type);
 
711
        cpu_abort(CPU(cpu), "Unknown machine check type %d\n", q->type);
699
712
    }
700
713
    if (!(env->cregs[14] & (1 << 28))) {
701
714
        /* CRW machine checks disabled */
744
757
    CPUS390XState *env = &cpu->env;
745
758
 
746
759
    qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
747
 
                  __func__, env->exception_index, env->psw.addr);
 
760
                  __func__, cs->exception_index, env->psw.addr);
748
761
 
749
762
    s390_add_running_cpu(cpu);
750
763
    /* handle machine checks */
751
764
    if ((env->psw.mask & PSW_MASK_MCHECK) &&
752
 
        (env->exception_index == -1)) {
 
765
        (cs->exception_index == -1)) {
753
766
        if (env->pending_int & INTERRUPT_MCHK) {
754
 
            env->exception_index = EXCP_MCHK;
 
767
            cs->exception_index = EXCP_MCHK;
755
768
        }
756
769
    }
757
770
    /* handle external interrupts */
758
771
    if ((env->psw.mask & PSW_MASK_EXT) &&
759
 
        env->exception_index == -1) {
 
772
        cs->exception_index == -1) {
760
773
        if (env->pending_int & INTERRUPT_EXT) {
761
774
            /* code is already in env */
762
 
            env->exception_index = EXCP_EXT;
 
775
            cs->exception_index = EXCP_EXT;
763
776
        } else if (env->pending_int & INTERRUPT_TOD) {
764
777
            cpu_inject_ext(cpu, 0x1004, 0, 0);
765
 
            env->exception_index = EXCP_EXT;
 
778
            cs->exception_index = EXCP_EXT;
766
779
            env->pending_int &= ~INTERRUPT_EXT;
767
780
            env->pending_int &= ~INTERRUPT_TOD;
768
781
        } else if (env->pending_int & INTERRUPT_CPUTIMER) {
769
782
            cpu_inject_ext(cpu, 0x1005, 0, 0);
770
 
            env->exception_index = EXCP_EXT;
 
783
            cs->exception_index = EXCP_EXT;
771
784
            env->pending_int &= ~INTERRUPT_EXT;
772
785
            env->pending_int &= ~INTERRUPT_TOD;
773
786
        }
774
787
    }
775
788
    /* handle I/O interrupts */
776
789
    if ((env->psw.mask & PSW_MASK_IO) &&
777
 
        (env->exception_index == -1)) {
 
790
        (cs->exception_index == -1)) {
778
791
        if (env->pending_int & INTERRUPT_IO) {
779
 
            env->exception_index = EXCP_IO;
 
792
            cs->exception_index = EXCP_IO;
780
793
        }
781
794
    }
782
795
 
783
 
    switch (env->exception_index) {
 
796
    switch (cs->exception_index) {
784
797
    case EXCP_PGM:
785
798
        do_program_interrupt(env);
786
799
        break;
797
810
        do_mchk_interrupt(env);
798
811
        break;
799
812
    }
800
 
    env->exception_index = -1;
 
813
    cs->exception_index = -1;
801
814
 
802
815
    if (!env->pending_int) {
803
816
        cs->interrupt_request &= ~CPU_INTERRUPT_HARD;