Statistics
| Branch: | Revision:

root / target-s390x / kvm.c @ a0fa2cb8

History | View | Annotate | Download (24.7 kB)

1 0e60a699 Alexander Graf
/*
2 0e60a699 Alexander Graf
 * QEMU S390x KVM implementation
3 0e60a699 Alexander Graf
 *
4 0e60a699 Alexander Graf
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 ccb084d3 Christian Borntraeger
 * Copyright IBM Corp. 2012
6 0e60a699 Alexander Graf
 *
7 0e60a699 Alexander Graf
 * This library is free software; you can redistribute it and/or
8 0e60a699 Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
9 0e60a699 Alexander Graf
 * License as published by the Free Software Foundation; either
10 0e60a699 Alexander Graf
 * version 2 of the License, or (at your option) any later version.
11 0e60a699 Alexander Graf
 *
12 0e60a699 Alexander Graf
 * This library is distributed in the hope that it will be useful,
13 0e60a699 Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 0e60a699 Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 0e60a699 Alexander Graf
 * Lesser General Public License for more details.
16 0e60a699 Alexander Graf
 *
17 ccb084d3 Christian Borntraeger
 * Contributions after 2012-10-29 are licensed under the terms of the
18 ccb084d3 Christian Borntraeger
 * GNU GPL, version 2 or (at your option) any later version.
19 ccb084d3 Christian Borntraeger
 *
20 ccb084d3 Christian Borntraeger
 * You should have received a copy of the GNU (Lesser) General Public
21 0e60a699 Alexander Graf
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 0e60a699 Alexander Graf
 */
23 0e60a699 Alexander Graf
24 0e60a699 Alexander Graf
#include <sys/types.h>
25 0e60a699 Alexander Graf
#include <sys/ioctl.h>
26 0e60a699 Alexander Graf
#include <sys/mman.h>
27 0e60a699 Alexander Graf
28 0e60a699 Alexander Graf
#include <linux/kvm.h>
29 0e60a699 Alexander Graf
#include <asm/ptrace.h>
30 0e60a699 Alexander Graf
31 0e60a699 Alexander Graf
#include "qemu-common.h"
32 1de7afc9 Paolo Bonzini
#include "qemu/timer.h"
33 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
34 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
35 0e60a699 Alexander Graf
#include "cpu.h"
36 9c17d615 Paolo Bonzini
#include "sysemu/device_tree.h"
37 08eb8c85 Christian Borntraeger
#include "qapi/qmp/qjson.h"
38 08eb8c85 Christian Borntraeger
#include "monitor/monitor.h"
39 0e60a699 Alexander Graf
40 0e60a699 Alexander Graf
/* #define DEBUG_KVM */
41 0e60a699 Alexander Graf
42 0e60a699 Alexander Graf
#ifdef DEBUG_KVM
43 e67137c6 Peter Maydell
#define DPRINTF(fmt, ...) \
44 0e60a699 Alexander Graf
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
45 0e60a699 Alexander Graf
#else
46 e67137c6 Peter Maydell
#define DPRINTF(fmt, ...) \
47 0e60a699 Alexander Graf
    do { } while (0)
48 0e60a699 Alexander Graf
#endif
49 0e60a699 Alexander Graf
50 0e60a699 Alexander Graf
#define IPA0_DIAG                       0x8300
51 0e60a699 Alexander Graf
#define IPA0_SIGP                       0xae00
52 09b99878 Cornelia Huck
#define IPA0_B2                         0xb200
53 09b99878 Cornelia Huck
#define IPA0_B9                         0xb900
54 09b99878 Cornelia Huck
#define IPA0_EB                         0xeb00
55 0e60a699 Alexander Graf
56 0e60a699 Alexander Graf
#define PRIV_SCLP_CALL                  0x20
57 09b99878 Cornelia Huck
#define PRIV_CSCH                       0x30
58 09b99878 Cornelia Huck
#define PRIV_HSCH                       0x31
59 09b99878 Cornelia Huck
#define PRIV_MSCH                       0x32
60 09b99878 Cornelia Huck
#define PRIV_SSCH                       0x33
61 09b99878 Cornelia Huck
#define PRIV_STSCH                      0x34
62 09b99878 Cornelia Huck
#define PRIV_TSCH                       0x35
63 09b99878 Cornelia Huck
#define PRIV_TPI                        0x36
64 09b99878 Cornelia Huck
#define PRIV_SAL                        0x37
65 09b99878 Cornelia Huck
#define PRIV_RSCH                       0x38
66 09b99878 Cornelia Huck
#define PRIV_STCRW                      0x39
67 09b99878 Cornelia Huck
#define PRIV_STCPS                      0x3a
68 09b99878 Cornelia Huck
#define PRIV_RCHP                       0x3b
69 09b99878 Cornelia Huck
#define PRIV_SCHM                       0x3c
70 09b99878 Cornelia Huck
#define PRIV_CHSC                       0x5f
71 09b99878 Cornelia Huck
#define PRIV_SIGA                       0x74
72 09b99878 Cornelia Huck
#define PRIV_XSCH                       0x76
73 09b99878 Cornelia Huck
#define PRIV_SQBS                       0x8a
74 09b99878 Cornelia Huck
#define PRIV_EQBS                       0x9c
75 268846ba Eugene (jno) Dvurechenski
#define DIAG_IPL                        0x308
76 0e60a699 Alexander Graf
#define DIAG_KVM_HYPERCALL              0x500
77 0e60a699 Alexander Graf
#define DIAG_KVM_BREAKPOINT             0x501
78 0e60a699 Alexander Graf
79 0e60a699 Alexander Graf
#define ICPT_INSTRUCTION                0x04
80 0e60a699 Alexander Graf
#define ICPT_WAITPSW                    0x1c
81 0e60a699 Alexander Graf
#define ICPT_SOFT_INTERCEPT             0x24
82 0e60a699 Alexander Graf
#define ICPT_CPU_STOP                   0x28
83 0e60a699 Alexander Graf
#define ICPT_IO                         0x40
84 0e60a699 Alexander Graf
85 94a8d39a Jan Kiszka
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
86 94a8d39a Jan Kiszka
    KVM_CAP_LAST_INFO
87 94a8d39a Jan Kiszka
};
88 94a8d39a Jan Kiszka
89 5b08b344 Christian Borntraeger
static int cap_sync_regs;
90 819bd309 Dominik Dingel
static int cap_async_pf;
91 5b08b344 Christian Borntraeger
92 575ddeb4 Stefan Weil
static void *legacy_s390_alloc(size_t size);
93 91138037 Markus Armbruster
94 cad1e282 Jan Kiszka
int kvm_arch_init(KVMState *s)
95 0e60a699 Alexander Graf
{
96 5b08b344 Christian Borntraeger
    cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
97 819bd309 Dominik Dingel
    cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
98 91138037 Markus Armbruster
    if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
99 91138037 Markus Armbruster
        || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
100 91138037 Markus Armbruster
        phys_mem_set_alloc(legacy_s390_alloc);
101 91138037 Markus Armbruster
    }
102 0e60a699 Alexander Graf
    return 0;
103 0e60a699 Alexander Graf
}
104 0e60a699 Alexander Graf
105 b164e48e Eduardo Habkost
unsigned long kvm_arch_vcpu_id(CPUState *cpu)
106 b164e48e Eduardo Habkost
{
107 b164e48e Eduardo Habkost
    return cpu->cpu_index;
108 b164e48e Eduardo Habkost
}
109 b164e48e Eduardo Habkost
110 20d695a9 Andreas Färber
int kvm_arch_init_vcpu(CPUState *cpu)
111 0e60a699 Alexander Graf
{
112 1c9d2a1d Christian Borntraeger
    /* nothing todo yet */
113 1c9d2a1d Christian Borntraeger
    return 0;
114 0e60a699 Alexander Graf
}
115 0e60a699 Alexander Graf
116 20d695a9 Andreas Färber
void kvm_arch_reset_vcpu(CPUState *cpu)
117 0e60a699 Alexander Graf
{
118 419831d7 Alexander Graf
    /* The initial reset call is needed here to reset in-kernel
119 419831d7 Alexander Graf
     * vcpu data that we can't access directly from QEMU
120 419831d7 Alexander Graf
     * (i.e. with older kernels which don't support sync_regs/ONE_REG).
121 419831d7 Alexander Graf
     * Before this ioctl cpu_synchronize_state() is called in common kvm
122 419831d7 Alexander Graf
     * code (kvm-all) */
123 70bada03 Jens Freimann
    if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) {
124 70bada03 Jens Freimann
        perror("Can't reset vcpu\n");
125 70bada03 Jens Freimann
    }
126 0e60a699 Alexander Graf
}
127 0e60a699 Alexander Graf
128 20d695a9 Andreas Färber
int kvm_arch_put_registers(CPUState *cs, int level)
129 0e60a699 Alexander Graf
{
130 20d695a9 Andreas Färber
    S390CPU *cpu = S390_CPU(cs);
131 20d695a9 Andreas Färber
    CPUS390XState *env = &cpu->env;
132 420840e5 Jason J. Herne
    struct kvm_one_reg reg;
133 5b08b344 Christian Borntraeger
    struct kvm_sregs sregs;
134 0e60a699 Alexander Graf
    struct kvm_regs regs;
135 0e60a699 Alexander Graf
    int ret;
136 0e60a699 Alexander Graf
    int i;
137 0e60a699 Alexander Graf
138 5b08b344 Christian Borntraeger
    /* always save the PSW  and the GPRS*/
139 f7575c96 Andreas Färber
    cs->kvm_run->psw_addr = env->psw.addr;
140 f7575c96 Andreas Färber
    cs->kvm_run->psw_mask = env->psw.mask;
141 0e60a699 Alexander Graf
142 f7575c96 Andreas Färber
    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
143 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
144 f7575c96 Andreas Färber
            cs->kvm_run->s.regs.gprs[i] = env->regs[i];
145 f7575c96 Andreas Färber
            cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GPRS;
146 5b08b344 Christian Borntraeger
        }
147 5b08b344 Christian Borntraeger
    } else {
148 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
149 5b08b344 Christian Borntraeger
            regs.gprs[i] = env->regs[i];
150 5b08b344 Christian Borntraeger
        }
151 1bc22652 Andreas Färber
        ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
152 5b08b344 Christian Borntraeger
        if (ret < 0) {
153 5b08b344 Christian Borntraeger
            return ret;
154 5b08b344 Christian Borntraeger
        }
155 0e60a699 Alexander Graf
    }
156 0e60a699 Alexander Graf
157 44c68de0 Dominik Dingel
    /* Do we need to save more than that? */
158 44c68de0 Dominik Dingel
    if (level == KVM_PUT_RUNTIME_STATE) {
159 44c68de0 Dominik Dingel
        return 0;
160 44c68de0 Dominik Dingel
    }
161 420840e5 Jason J. Herne
162 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_CPU_TIMER;
163 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->cputm);
164 44c68de0 Dominik Dingel
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
165 44c68de0 Dominik Dingel
    if (ret < 0) {
166 44c68de0 Dominik Dingel
        return ret;
167 44c68de0 Dominik Dingel
    }
168 420840e5 Jason J. Herne
169 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_CLOCK_COMP;
170 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->ckc);
171 44c68de0 Dominik Dingel
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
172 44c68de0 Dominik Dingel
    if (ret < 0) {
173 44c68de0 Dominik Dingel
        return ret;
174 420840e5 Jason J. Herne
    }
175 420840e5 Jason J. Herne
176 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_TODPR;
177 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->todpr);
178 44c68de0 Dominik Dingel
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
179 44c68de0 Dominik Dingel
    if (ret < 0) {
180 44c68de0 Dominik Dingel
        return ret;
181 0e60a699 Alexander Graf
    }
182 0e60a699 Alexander Graf
183 819bd309 Dominik Dingel
    if (cap_async_pf) {
184 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFTOKEN;
185 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_token);
186 819bd309 Dominik Dingel
        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
187 819bd309 Dominik Dingel
        if (ret < 0) {
188 819bd309 Dominik Dingel
            return ret;
189 819bd309 Dominik Dingel
        }
190 819bd309 Dominik Dingel
191 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFCOMPARE;
192 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_compare);
193 819bd309 Dominik Dingel
        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
194 819bd309 Dominik Dingel
        if (ret < 0) {
195 819bd309 Dominik Dingel
            return ret;
196 819bd309 Dominik Dingel
        }
197 819bd309 Dominik Dingel
198 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFSELECT;
199 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_select);
200 819bd309 Dominik Dingel
        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
201 819bd309 Dominik Dingel
        if (ret < 0) {
202 819bd309 Dominik Dingel
            return ret;
203 819bd309 Dominik Dingel
        }
204 819bd309 Dominik Dingel
    }
205 819bd309 Dominik Dingel
206 5b08b344 Christian Borntraeger
    if (cap_sync_regs &&
207 f7575c96 Andreas Färber
        cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
208 f7575c96 Andreas Färber
        cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
209 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
210 f7575c96 Andreas Färber
            cs->kvm_run->s.regs.acrs[i] = env->aregs[i];
211 f7575c96 Andreas Färber
            cs->kvm_run->s.regs.crs[i] = env->cregs[i];
212 5b08b344 Christian Borntraeger
        }
213 f7575c96 Andreas Färber
        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ACRS;
214 f7575c96 Andreas Färber
        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_CRS;
215 5b08b344 Christian Borntraeger
    } else {
216 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
217 5b08b344 Christian Borntraeger
            sregs.acrs[i] = env->aregs[i];
218 5b08b344 Christian Borntraeger
            sregs.crs[i] = env->cregs[i];
219 5b08b344 Christian Borntraeger
        }
220 1bc22652 Andreas Färber
        ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
221 5b08b344 Christian Borntraeger
        if (ret < 0) {
222 5b08b344 Christian Borntraeger
            return ret;
223 5b08b344 Christian Borntraeger
        }
224 5b08b344 Christian Borntraeger
    }
225 0e60a699 Alexander Graf
226 5b08b344 Christian Borntraeger
    /* Finally the prefix */
227 f7575c96 Andreas Färber
    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
228 f7575c96 Andreas Färber
        cs->kvm_run->s.regs.prefix = env->psa;
229 f7575c96 Andreas Färber
        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_PREFIX;
230 5b08b344 Christian Borntraeger
    } else {
231 5b08b344 Christian Borntraeger
        /* prefix is only supported via sync regs */
232 5b08b344 Christian Borntraeger
    }
233 5b08b344 Christian Borntraeger
    return 0;
234 0e60a699 Alexander Graf
}
235 0e60a699 Alexander Graf
236 20d695a9 Andreas Färber
int kvm_arch_get_registers(CPUState *cs)
237 0e60a699 Alexander Graf
{
238 20d695a9 Andreas Färber
    S390CPU *cpu = S390_CPU(cs);
239 20d695a9 Andreas Färber
    CPUS390XState *env = &cpu->env;
240 420840e5 Jason J. Herne
    struct kvm_one_reg reg;
241 5b08b344 Christian Borntraeger
    struct kvm_sregs sregs;
242 0e60a699 Alexander Graf
    struct kvm_regs regs;
243 44c68de0 Dominik Dingel
    int i, r;
244 420840e5 Jason J. Herne
245 5b08b344 Christian Borntraeger
    /* get the PSW */
246 f7575c96 Andreas Färber
    env->psw.addr = cs->kvm_run->psw_addr;
247 f7575c96 Andreas Färber
    env->psw.mask = cs->kvm_run->psw_mask;
248 5b08b344 Christian Borntraeger
249 5b08b344 Christian Borntraeger
    /* the GPRS */
250 f7575c96 Andreas Färber
    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
251 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
252 f7575c96 Andreas Färber
            env->regs[i] = cs->kvm_run->s.regs.gprs[i];
253 5b08b344 Christian Borntraeger
        }
254 5b08b344 Christian Borntraeger
    } else {
255 44c68de0 Dominik Dingel
        r = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
256 44c68de0 Dominik Dingel
        if (r < 0) {
257 44c68de0 Dominik Dingel
            return r;
258 5b08b344 Christian Borntraeger
        }
259 5b08b344 Christian Borntraeger
         for (i = 0; i < 16; i++) {
260 5b08b344 Christian Borntraeger
            env->regs[i] = regs.gprs[i];
261 5b08b344 Christian Borntraeger
        }
262 0e60a699 Alexander Graf
    }
263 0e60a699 Alexander Graf
264 5b08b344 Christian Borntraeger
    /* The ACRS and CRS */
265 5b08b344 Christian Borntraeger
    if (cap_sync_regs &&
266 f7575c96 Andreas Färber
        cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
267 f7575c96 Andreas Färber
        cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
268 5b08b344 Christian Borntraeger
        for (i = 0; i < 16; i++) {
269 f7575c96 Andreas Färber
            env->aregs[i] = cs->kvm_run->s.regs.acrs[i];
270 f7575c96 Andreas Färber
            env->cregs[i] = cs->kvm_run->s.regs.crs[i];
271 5b08b344 Christian Borntraeger
        }
272 5b08b344 Christian Borntraeger
    } else {
273 44c68de0 Dominik Dingel
        r = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
274 44c68de0 Dominik Dingel
        if (r < 0) {
275 44c68de0 Dominik Dingel
            return r;
276 5b08b344 Christian Borntraeger
        }
277 5b08b344 Christian Borntraeger
         for (i = 0; i < 16; i++) {
278 5b08b344 Christian Borntraeger
            env->aregs[i] = sregs.acrs[i];
279 5b08b344 Christian Borntraeger
            env->cregs[i] = sregs.crs[i];
280 5b08b344 Christian Borntraeger
        }
281 0e60a699 Alexander Graf
    }
282 0e60a699 Alexander Graf
283 44c68de0 Dominik Dingel
    /* The prefix */
284 f7575c96 Andreas Färber
    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
285 f7575c96 Andreas Färber
        env->psa = cs->kvm_run->s.regs.prefix;
286 5b08b344 Christian Borntraeger
    }
287 0e60a699 Alexander Graf
288 44c68de0 Dominik Dingel
    /* One Regs */
289 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_CPU_TIMER;
290 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->cputm);
291 44c68de0 Dominik Dingel
    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
292 44c68de0 Dominik Dingel
    if (r < 0) {
293 44c68de0 Dominik Dingel
        return r;
294 44c68de0 Dominik Dingel
    }
295 44c68de0 Dominik Dingel
296 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_CLOCK_COMP;
297 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->ckc);
298 44c68de0 Dominik Dingel
    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
299 44c68de0 Dominik Dingel
    if (r < 0) {
300 44c68de0 Dominik Dingel
        return r;
301 44c68de0 Dominik Dingel
    }
302 44c68de0 Dominik Dingel
303 44c68de0 Dominik Dingel
    reg.id = KVM_REG_S390_TODPR;
304 44c68de0 Dominik Dingel
    reg.addr = (__u64)&(env->todpr);
305 44c68de0 Dominik Dingel
    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
306 44c68de0 Dominik Dingel
    if (r < 0) {
307 44c68de0 Dominik Dingel
        return r;
308 44c68de0 Dominik Dingel
    }
309 44c68de0 Dominik Dingel
310 819bd309 Dominik Dingel
    if (cap_async_pf) {
311 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFTOKEN;
312 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_token);
313 819bd309 Dominik Dingel
        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
314 819bd309 Dominik Dingel
        if (r < 0) {
315 819bd309 Dominik Dingel
            return r;
316 819bd309 Dominik Dingel
        }
317 819bd309 Dominik Dingel
318 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFCOMPARE;
319 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_compare);
320 819bd309 Dominik Dingel
        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
321 819bd309 Dominik Dingel
        if (r < 0) {
322 819bd309 Dominik Dingel
            return r;
323 819bd309 Dominik Dingel
        }
324 819bd309 Dominik Dingel
325 819bd309 Dominik Dingel
        reg.id = KVM_REG_S390_PFSELECT;
326 819bd309 Dominik Dingel
        reg.addr = (__u64)&(env->pfault_select);
327 819bd309 Dominik Dingel
        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
328 819bd309 Dominik Dingel
        if (r < 0) {
329 819bd309 Dominik Dingel
            return r;
330 819bd309 Dominik Dingel
        }
331 819bd309 Dominik Dingel
    }
332 819bd309 Dominik Dingel
333 0e60a699 Alexander Graf
    return 0;
334 0e60a699 Alexander Graf
}
335 0e60a699 Alexander Graf
336 fdec9918 Christian Borntraeger
/*
337 fdec9918 Christian Borntraeger
 * Legacy layout for s390:
338 fdec9918 Christian Borntraeger
 * Older S390 KVM requires the topmost vma of the RAM to be
339 fdec9918 Christian Borntraeger
 * smaller than an system defined value, which is at least 256GB.
340 fdec9918 Christian Borntraeger
 * Larger systems have larger values. We put the guest between
341 fdec9918 Christian Borntraeger
 * the end of data segment (system break) and this value. We
342 fdec9918 Christian Borntraeger
 * use 32GB as a base to have enough room for the system break
343 fdec9918 Christian Borntraeger
 * to grow. We also have to use MAP parameters that avoid
344 fdec9918 Christian Borntraeger
 * read-only mapping of guest pages.
345 fdec9918 Christian Borntraeger
 */
346 575ddeb4 Stefan Weil
static void *legacy_s390_alloc(size_t size)
347 fdec9918 Christian Borntraeger
{
348 fdec9918 Christian Borntraeger
    void *mem;
349 fdec9918 Christian Borntraeger
350 fdec9918 Christian Borntraeger
    mem = mmap((void *) 0x800000000ULL, size,
351 fdec9918 Christian Borntraeger
               PROT_EXEC|PROT_READ|PROT_WRITE,
352 fdec9918 Christian Borntraeger
               MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
353 39228250 Markus Armbruster
    return mem == MAP_FAILED ? NULL : mem;
354 fdec9918 Christian Borntraeger
}
355 fdec9918 Christian Borntraeger
356 20d695a9 Andreas Färber
int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
357 0e60a699 Alexander Graf
{
358 0e60a699 Alexander Graf
    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
359 0e60a699 Alexander Graf
360 9282b73a Christian Borntraeger
    if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
361 9282b73a Christian Borntraeger
        cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501, 4, 1)) {
362 0e60a699 Alexander Graf
        return -EINVAL;
363 0e60a699 Alexander Graf
    }
364 0e60a699 Alexander Graf
    return 0;
365 0e60a699 Alexander Graf
}
366 0e60a699 Alexander Graf
367 20d695a9 Andreas Färber
int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
368 0e60a699 Alexander Graf
{
369 0e60a699 Alexander Graf
    uint8_t t[4];
370 0e60a699 Alexander Graf
    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
371 0e60a699 Alexander Graf
372 9282b73a Christian Borntraeger
    if (cpu_memory_rw_debug(cs, bp->pc, t, 4, 0)) {
373 0e60a699 Alexander Graf
        return -EINVAL;
374 0e60a699 Alexander Graf
    } else if (memcmp(t, diag_501, 4)) {
375 0e60a699 Alexander Graf
        return -EINVAL;
376 9282b73a Christian Borntraeger
    } else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
377 0e60a699 Alexander Graf
        return -EINVAL;
378 0e60a699 Alexander Graf
    }
379 0e60a699 Alexander Graf
380 0e60a699 Alexander Graf
    return 0;
381 0e60a699 Alexander Graf
}
382 0e60a699 Alexander Graf
383 20d695a9 Andreas Färber
void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
384 0e60a699 Alexander Graf
{
385 0e60a699 Alexander Graf
}
386 0e60a699 Alexander Graf
387 20d695a9 Andreas Färber
void kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
388 0e60a699 Alexander Graf
{
389 0e60a699 Alexander Graf
}
390 0e60a699 Alexander Graf
391 20d695a9 Andreas Färber
int kvm_arch_process_async_events(CPUState *cs)
392 0af691d7 Marcelo Tosatti
{
393 225dc991 Cornelia Huck
    return cs->halted;
394 0af691d7 Marcelo Tosatti
}
395 0af691d7 Marcelo Tosatti
396 1bc22652 Andreas Färber
void kvm_s390_interrupt_internal(S390CPU *cpu, int type, uint32_t parm,
397 bcec36ea Alexander Graf
                                 uint64_t parm64, int vm)
398 0e60a699 Alexander Graf
{
399 1bc22652 Andreas Färber
    CPUState *cs = CPU(cpu);
400 0e60a699 Alexander Graf
    struct kvm_s390_interrupt kvmint;
401 0e60a699 Alexander Graf
    int r;
402 0e60a699 Alexander Graf
403 a60f24b5 Andreas Färber
    if (!cs->kvm_state) {
404 0e60a699 Alexander Graf
        return;
405 0e60a699 Alexander Graf
    }
406 0e60a699 Alexander Graf
407 0e60a699 Alexander Graf
    kvmint.type = type;
408 0e60a699 Alexander Graf
    kvmint.parm = parm;
409 0e60a699 Alexander Graf
    kvmint.parm64 = parm64;
410 0e60a699 Alexander Graf
411 0e60a699 Alexander Graf
    if (vm) {
412 a60f24b5 Andreas Färber
        r = kvm_vm_ioctl(cs->kvm_state, KVM_S390_INTERRUPT, &kvmint);
413 0e60a699 Alexander Graf
    } else {
414 1bc22652 Andreas Färber
        r = kvm_vcpu_ioctl(cs, KVM_S390_INTERRUPT, &kvmint);
415 0e60a699 Alexander Graf
    }
416 0e60a699 Alexander Graf
417 0e60a699 Alexander Graf
    if (r < 0) {
418 0e60a699 Alexander Graf
        fprintf(stderr, "KVM failed to inject interrupt\n");
419 0e60a699 Alexander Graf
        exit(1);
420 0e60a699 Alexander Graf
    }
421 0e60a699 Alexander Graf
}
422 0e60a699 Alexander Graf
423 1bc22652 Andreas Färber
void kvm_s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token)
424 0e60a699 Alexander Graf
{
425 1bc22652 Andreas Färber
    kvm_s390_interrupt_internal(cpu, KVM_S390_INT_VIRTIO, config_change,
426 0e60a699 Alexander Graf
                                token, 1);
427 0e60a699 Alexander Graf
}
428 0e60a699 Alexander Graf
429 1bc22652 Andreas Färber
void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code)
430 0e60a699 Alexander Graf
{
431 1bc22652 Andreas Färber
    kvm_s390_interrupt_internal(cpu, type, code, 0, 0);
432 0e60a699 Alexander Graf
}
433 0e60a699 Alexander Graf
434 1bc22652 Andreas Färber
static void enter_pgmcheck(S390CPU *cpu, uint16_t code)
435 0e60a699 Alexander Graf
{
436 1bc22652 Andreas Färber
    kvm_s390_interrupt(cpu, KVM_S390_PROGRAM_INT, code);
437 0e60a699 Alexander Graf
}
438 0e60a699 Alexander Graf
439 1bc22652 Andreas Färber
static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
440 bcec36ea Alexander Graf
                                 uint16_t ipbh0)
441 0e60a699 Alexander Graf
{
442 1bc22652 Andreas Färber
    CPUS390XState *env = &cpu->env;
443 a0fa2cb8 Thomas Huth
    uint64_t sccb;
444 a0fa2cb8 Thomas Huth
    uint32_t code;
445 0e60a699 Alexander Graf
    int r = 0;
446 0e60a699 Alexander Graf
447 cb446eca Andreas Färber
    cpu_synchronize_state(CPU(cpu));
448 3ac85fb6 Thomas Huth
    if (env->psw.mask & PSW_MASK_PSTATE) {
449 3ac85fb6 Thomas Huth
        enter_pgmcheck(cpu, PGM_PRIVILEGED);
450 3ac85fb6 Thomas Huth
        return 0;
451 3ac85fb6 Thomas Huth
    }
452 0e60a699 Alexander Graf
    sccb = env->regs[ipbh0 & 0xf];
453 0e60a699 Alexander Graf
    code = env->regs[(ipbh0 & 0xf0) >> 4];
454 0e60a699 Alexander Graf
455 f6c98f92 Heinz Graalfs
    r = sclp_service_call(sccb, code);
456 9abf567d Christian Borntraeger
    if (r < 0) {
457 1bc22652 Andreas Färber
        enter_pgmcheck(cpu, -r);
458 0e60a699 Alexander Graf
    }
459 f7575c96 Andreas Färber
    setcc(cpu, r);
460 81f7c56c Alexander Graf
461 0e60a699 Alexander Graf
    return 0;
462 0e60a699 Alexander Graf
}
463 0e60a699 Alexander Graf
464 09b99878 Cornelia Huck
static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
465 09b99878 Cornelia Huck
                               uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
466 09b99878 Cornelia Huck
{
467 09b99878 Cornelia Huck
    CPUS390XState *env = &cpu->env;
468 09b99878 Cornelia Huck
469 09b99878 Cornelia Huck
    if (ipa0 != 0xb2) {
470 09b99878 Cornelia Huck
        /* Not handled for now. */
471 09b99878 Cornelia Huck
        return -1;
472 09b99878 Cornelia Huck
    }
473 3474b679 Jason J. Herne
474 44c68de0 Dominik Dingel
    cpu_synchronize_state(CPU(cpu));
475 3474b679 Jason J. Herne
476 09b99878 Cornelia Huck
    switch (ipa1) {
477 09b99878 Cornelia Huck
    case PRIV_XSCH:
478 5d9bf1c0 Thomas Huth
        ioinst_handle_xsch(cpu, env->regs[1]);
479 09b99878 Cornelia Huck
        break;
480 09b99878 Cornelia Huck
    case PRIV_CSCH:
481 5d9bf1c0 Thomas Huth
        ioinst_handle_csch(cpu, env->regs[1]);
482 09b99878 Cornelia Huck
        break;
483 09b99878 Cornelia Huck
    case PRIV_HSCH:
484 5d9bf1c0 Thomas Huth
        ioinst_handle_hsch(cpu, env->regs[1]);
485 09b99878 Cornelia Huck
        break;
486 09b99878 Cornelia Huck
    case PRIV_MSCH:
487 5d9bf1c0 Thomas Huth
        ioinst_handle_msch(cpu, env->regs[1], run->s390_sieic.ipb);
488 09b99878 Cornelia Huck
        break;
489 09b99878 Cornelia Huck
    case PRIV_SSCH:
490 5d9bf1c0 Thomas Huth
        ioinst_handle_ssch(cpu, env->regs[1], run->s390_sieic.ipb);
491 09b99878 Cornelia Huck
        break;
492 09b99878 Cornelia Huck
    case PRIV_STCRW:
493 5d9bf1c0 Thomas Huth
        ioinst_handle_stcrw(cpu, run->s390_sieic.ipb);
494 09b99878 Cornelia Huck
        break;
495 09b99878 Cornelia Huck
    case PRIV_STSCH:
496 5d9bf1c0 Thomas Huth
        ioinst_handle_stsch(cpu, env->regs[1], run->s390_sieic.ipb);
497 09b99878 Cornelia Huck
        break;
498 09b99878 Cornelia Huck
    case PRIV_TSCH:
499 09b99878 Cornelia Huck
        /* We should only get tsch via KVM_EXIT_S390_TSCH. */
500 09b99878 Cornelia Huck
        fprintf(stderr, "Spurious tsch intercept\n");
501 09b99878 Cornelia Huck
        break;
502 09b99878 Cornelia Huck
    case PRIV_CHSC:
503 5d9bf1c0 Thomas Huth
        ioinst_handle_chsc(cpu, run->s390_sieic.ipb);
504 09b99878 Cornelia Huck
        break;
505 09b99878 Cornelia Huck
    case PRIV_TPI:
506 09b99878 Cornelia Huck
        /* This should have been handled by kvm already. */
507 09b99878 Cornelia Huck
        fprintf(stderr, "Spurious tpi intercept\n");
508 09b99878 Cornelia Huck
        break;
509 09b99878 Cornelia Huck
    case PRIV_SCHM:
510 5d9bf1c0 Thomas Huth
        ioinst_handle_schm(cpu, env->regs[1], env->regs[2],
511 5d9bf1c0 Thomas Huth
                           run->s390_sieic.ipb);
512 09b99878 Cornelia Huck
        break;
513 09b99878 Cornelia Huck
    case PRIV_RSCH:
514 5d9bf1c0 Thomas Huth
        ioinst_handle_rsch(cpu, env->regs[1]);
515 09b99878 Cornelia Huck
        break;
516 09b99878 Cornelia Huck
    case PRIV_RCHP:
517 5d9bf1c0 Thomas Huth
        ioinst_handle_rchp(cpu, env->regs[1]);
518 09b99878 Cornelia Huck
        break;
519 09b99878 Cornelia Huck
    case PRIV_STCPS:
520 09b99878 Cornelia Huck
        /* We do not provide this instruction, it is suppressed. */
521 09b99878 Cornelia Huck
        break;
522 09b99878 Cornelia Huck
    case PRIV_SAL:
523 5d9bf1c0 Thomas Huth
        ioinst_handle_sal(cpu, env->regs[1]);
524 09b99878 Cornelia Huck
        break;
525 c1e8dfb5 Thomas Huth
    case PRIV_SIGA:
526 c1e8dfb5 Thomas Huth
        /* Not provided, set CC = 3 for subchannel not operational */
527 5d9bf1c0 Thomas Huth
        setcc(cpu, 3);
528 09b99878 Cornelia Huck
        break;
529 c1e8dfb5 Thomas Huth
    default:
530 c1e8dfb5 Thomas Huth
        return -1;
531 09b99878 Cornelia Huck
    }
532 09b99878 Cornelia Huck
533 c1e8dfb5 Thomas Huth
    return 0;
534 09b99878 Cornelia Huck
}
535 09b99878 Cornelia Huck
536 09b99878 Cornelia Huck
static int handle_priv(S390CPU *cpu, struct kvm_run *run,
537 09b99878 Cornelia Huck
                       uint8_t ipa0, uint8_t ipa1)
538 0e60a699 Alexander Graf
{
539 0e60a699 Alexander Graf
    int r = 0;
540 0e60a699 Alexander Graf
    uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
541 09b99878 Cornelia Huck
    uint8_t ipb = run->s390_sieic.ipb & 0xff;
542 0e60a699 Alexander Graf
543 e67137c6 Peter Maydell
    DPRINTF("KVM: PRIV: %d\n", ipa1);
544 0e60a699 Alexander Graf
    switch (ipa1) {
545 0e60a699 Alexander Graf
        case PRIV_SCLP_CALL:
546 1bc22652 Andreas Färber
            r = kvm_sclp_service_call(cpu, run, ipbh0);
547 0e60a699 Alexander Graf
            break;
548 0e60a699 Alexander Graf
        default:
549 c1e8dfb5 Thomas Huth
            r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
550 c1e8dfb5 Thomas Huth
            if (r == -1) {
551 c1e8dfb5 Thomas Huth
                DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1);
552 09b99878 Cornelia Huck
            }
553 0e60a699 Alexander Graf
            break;
554 0e60a699 Alexander Graf
    }
555 0e60a699 Alexander Graf
556 0e60a699 Alexander Graf
    return r;
557 0e60a699 Alexander Graf
}
558 0e60a699 Alexander Graf
559 4fd6dd06 Andreas Färber
static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
560 0e60a699 Alexander Graf
{
561 4fd6dd06 Andreas Färber
    CPUS390XState *env = &cpu->env;
562 77319f22 Thomas Huth
    int ret;
563 3474b679 Jason J. Herne
564 44c68de0 Dominik Dingel
    cpu_synchronize_state(CPU(cpu));
565 77319f22 Thomas Huth
    ret = s390_virtio_hypercall(env);
566 77319f22 Thomas Huth
    if (ret == -EINVAL) {
567 77319f22 Thomas Huth
        enter_pgmcheck(cpu, PGM_SPECIFICATION);
568 77319f22 Thomas Huth
        return 0;
569 77319f22 Thomas Huth
    }
570 0e60a699 Alexander Graf
571 77319f22 Thomas Huth
    return ret;
572 0e60a699 Alexander Graf
}
573 0e60a699 Alexander Graf
574 268846ba Eugene (jno) Dvurechenski
static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
575 268846ba Eugene (jno) Dvurechenski
{
576 268846ba Eugene (jno) Dvurechenski
    uint64_t r1, r3;
577 268846ba Eugene (jno) Dvurechenski
578 268846ba Eugene (jno) Dvurechenski
    cpu_synchronize_state(CPU(cpu));
579 268846ba Eugene (jno) Dvurechenski
    r1 = (run->s390_sieic.ipa & 0x00f0) >> 8;
580 268846ba Eugene (jno) Dvurechenski
    r3 = run->s390_sieic.ipa & 0x000f;
581 268846ba Eugene (jno) Dvurechenski
    handle_diag_308(&cpu->env, r1, r3);
582 268846ba Eugene (jno) Dvurechenski
}
583 268846ba Eugene (jno) Dvurechenski
584 638129ff Cornelia Huck
#define DIAG_KVM_CODE_MASK 0x000000000000ffff
585 638129ff Cornelia Huck
586 638129ff Cornelia Huck
static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
587 0e60a699 Alexander Graf
{
588 0e60a699 Alexander Graf
    int r = 0;
589 638129ff Cornelia Huck
    uint16_t func_code;
590 638129ff Cornelia Huck
591 638129ff Cornelia Huck
    /*
592 638129ff Cornelia Huck
     * For any diagnose call we support, bits 48-63 of the resulting
593 638129ff Cornelia Huck
     * address specify the function code; the remainder is ignored.
594 638129ff Cornelia Huck
     */
595 638129ff Cornelia Huck
    func_code = decode_basedisp_rs(&cpu->env, ipb) & DIAG_KVM_CODE_MASK;
596 638129ff Cornelia Huck
    switch (func_code) {
597 268846ba Eugene (jno) Dvurechenski
    case DIAG_IPL:
598 268846ba Eugene (jno) Dvurechenski
        kvm_handle_diag_308(cpu, run);
599 268846ba Eugene (jno) Dvurechenski
        break;
600 39fbc5c6 Christian Borntraeger
    case DIAG_KVM_HYPERCALL:
601 39fbc5c6 Christian Borntraeger
        r = handle_hypercall(cpu, run);
602 39fbc5c6 Christian Borntraeger
        break;
603 39fbc5c6 Christian Borntraeger
    case DIAG_KVM_BREAKPOINT:
604 39fbc5c6 Christian Borntraeger
        sleep(10);
605 39fbc5c6 Christian Borntraeger
        break;
606 39fbc5c6 Christian Borntraeger
    default:
607 638129ff Cornelia Huck
        DPRINTF("KVM: unknown DIAG: 0x%x\n", func_code);
608 39fbc5c6 Christian Borntraeger
        r = -1;
609 39fbc5c6 Christian Borntraeger
        break;
610 0e60a699 Alexander Graf
    }
611 0e60a699 Alexander Graf
612 0e60a699 Alexander Graf
    return r;
613 0e60a699 Alexander Graf
}
614 0e60a699 Alexander Graf
615 b20a461f Thomas Huth
static int kvm_s390_cpu_start(S390CPU *cpu)
616 b20a461f Thomas Huth
{
617 b20a461f Thomas Huth
    s390_add_running_cpu(cpu);
618 b20a461f Thomas Huth
    qemu_cpu_kick(CPU(cpu));
619 b20a461f Thomas Huth
    DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env);
620 b20a461f Thomas Huth
    return 0;
621 b20a461f Thomas Huth
}
622 b20a461f Thomas Huth
623 7f7f9752 Eugene (jno) Dvurechenski
int kvm_s390_cpu_restart(S390CPU *cpu)
624 0e60a699 Alexander Graf
{
625 1bc22652 Andreas Färber
    kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0);
626 49e15878 Andreas Färber
    s390_add_running_cpu(cpu);
627 c08d7424 Andreas Färber
    qemu_cpu_kick(CPU(cpu));
628 7f7f9752 Eugene (jno) Dvurechenski
    DPRINTF("DONE: KVM cpu restart: %p\n", &cpu->env);
629 0e60a699 Alexander Graf
    return 0;
630 0e60a699 Alexander Graf
}
631 0e60a699 Alexander Graf
632 1bc22652 Andreas Färber
static int s390_cpu_initial_reset(S390CPU *cpu)
633 0e60a699 Alexander Graf
{
634 cb446eca Andreas Färber
    CPUState *cs = CPU(cpu);
635 1bc22652 Andreas Färber
    CPUS390XState *env = &cpu->env;
636 d5900813 Alexander Graf
    int i;
637 d5900813 Alexander Graf
638 49e15878 Andreas Färber
    s390_del_running_cpu(cpu);
639 cb446eca Andreas Färber
    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
640 d5900813 Alexander Graf
        perror("cannot init reset vcpu");
641 d5900813 Alexander Graf
    }
642 d5900813 Alexander Graf
643 d5900813 Alexander Graf
    /* Manually zero out all registers */
644 cb446eca Andreas Färber
    cpu_synchronize_state(cs);
645 d5900813 Alexander Graf
    for (i = 0; i < 16; i++) {
646 d5900813 Alexander Graf
        env->regs[i] = 0;
647 d5900813 Alexander Graf
    }
648 d5900813 Alexander Graf
649 e67137c6 Peter Maydell
    DPRINTF("DONE: SIGP initial reset: %p\n", env);
650 d5900813 Alexander Graf
    return 0;
651 0e60a699 Alexander Graf
}
652 0e60a699 Alexander Graf
653 b8031adb Thomas Huth
#define SIGP_ORDER_MASK 0x000000ff
654 b8031adb Thomas Huth
655 f7575c96 Andreas Färber
static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
656 0e60a699 Alexander Graf
{
657 f7575c96 Andreas Färber
    CPUS390XState *env = &cpu->env;
658 0e60a699 Alexander Graf
    uint8_t order_code;
659 0e60a699 Alexander Graf
    uint16_t cpu_addr;
660 45fa769b Andreas Färber
    S390CPU *target_cpu;
661 3796f0e1 Thomas Huth
    uint64_t *statusreg = &env->regs[ipa1 >> 4];
662 3796f0e1 Thomas Huth
    int cc;
663 0e60a699 Alexander Graf
664 cb446eca Andreas Färber
    cpu_synchronize_state(CPU(cpu));
665 0e60a699 Alexander Graf
666 0e60a699 Alexander Graf
    /* get order code */
667 b8031adb Thomas Huth
    order_code = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK;
668 0e60a699 Alexander Graf
669 0e60a699 Alexander Graf
    cpu_addr = env->regs[ipa1 & 0x0f];
670 45fa769b Andreas Färber
    target_cpu = s390_cpu_addr2state(cpu_addr);
671 45fa769b Andreas Färber
    if (target_cpu == NULL) {
672 3796f0e1 Thomas Huth
        cc = 3;    /* not operational */
673 0e60a699 Alexander Graf
        goto out;
674 0e60a699 Alexander Graf
    }
675 0e60a699 Alexander Graf
676 0e60a699 Alexander Graf
    switch (order_code) {
677 b20a461f Thomas Huth
    case SIGP_START:
678 3796f0e1 Thomas Huth
        cc = kvm_s390_cpu_start(target_cpu);
679 b20a461f Thomas Huth
        break;
680 0b9972a2 Thomas Huth
    case SIGP_RESTART:
681 3796f0e1 Thomas Huth
        cc = kvm_s390_cpu_restart(target_cpu);
682 0b9972a2 Thomas Huth
        break;
683 0b9972a2 Thomas Huth
    case SIGP_SET_ARCH:
684 0788082a Thomas Huth
        *statusreg &= 0xffffffff00000000UL;
685 0788082a Thomas Huth
        *statusreg |= SIGP_STAT_INVALID_PARAMETER;
686 0788082a Thomas Huth
        cc = 1;   /* status stored */
687 0788082a Thomas Huth
        break;
688 0b9972a2 Thomas Huth
    case SIGP_INITIAL_CPU_RESET:
689 3796f0e1 Thomas Huth
        cc = s390_cpu_initial_reset(target_cpu);
690 0b9972a2 Thomas Huth
        break;
691 0b9972a2 Thomas Huth
    default:
692 3796f0e1 Thomas Huth
        DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code);
693 3796f0e1 Thomas Huth
        *statusreg &= 0xffffffff00000000UL;
694 3796f0e1 Thomas Huth
        *statusreg |= SIGP_STAT_INVALID_ORDER;
695 3796f0e1 Thomas Huth
        cc = 1;   /* status stored */
696 0b9972a2 Thomas Huth
        break;
697 0e60a699 Alexander Graf
    }
698 0e60a699 Alexander Graf
699 0e60a699 Alexander Graf
out:
700 3796f0e1 Thomas Huth
    setcc(cpu, cc);
701 0e60a699 Alexander Graf
    return 0;
702 0e60a699 Alexander Graf
}
703 0e60a699 Alexander Graf
704 d2ee7746 Thomas Huth
static void handle_instruction(S390CPU *cpu, struct kvm_run *run)
705 0e60a699 Alexander Graf
{
706 0e60a699 Alexander Graf
    unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
707 0e60a699 Alexander Graf
    uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
708 d7963c43 Alexander Graf
    int r = -1;
709 0e60a699 Alexander Graf
710 e67137c6 Peter Maydell
    DPRINTF("handle_instruction 0x%x 0x%x\n",
711 e67137c6 Peter Maydell
            run->s390_sieic.ipa, run->s390_sieic.ipb);
712 0e60a699 Alexander Graf
    switch (ipa0) {
713 09b99878 Cornelia Huck
    case IPA0_B2:
714 09b99878 Cornelia Huck
    case IPA0_B9:
715 09b99878 Cornelia Huck
    case IPA0_EB:
716 09b99878 Cornelia Huck
        r = handle_priv(cpu, run, ipa0 >> 8, ipa1);
717 09b99878 Cornelia Huck
        break;
718 09b99878 Cornelia Huck
    case IPA0_DIAG:
719 638129ff Cornelia Huck
        r = handle_diag(cpu, run, run->s390_sieic.ipb);
720 09b99878 Cornelia Huck
        break;
721 09b99878 Cornelia Huck
    case IPA0_SIGP:
722 09b99878 Cornelia Huck
        r = handle_sigp(cpu, run, ipa1);
723 09b99878 Cornelia Huck
        break;
724 0e60a699 Alexander Graf
    }
725 0e60a699 Alexander Graf
726 0e60a699 Alexander Graf
    if (r < 0) {
727 1bc22652 Andreas Färber
        enter_pgmcheck(cpu, 0x0001);
728 0e60a699 Alexander Graf
    }
729 0e60a699 Alexander Graf
}
730 0e60a699 Alexander Graf
731 f7575c96 Andreas Färber
static bool is_special_wait_psw(CPUState *cs)
732 eca3ed03 Christian Borntraeger
{
733 eca3ed03 Christian Borntraeger
    /* signal quiesce */
734 f7575c96 Andreas Färber
    return cs->kvm_run->psw_addr == 0xfffUL;
735 eca3ed03 Christian Borntraeger
}
736 eca3ed03 Christian Borntraeger
737 1bc22652 Andreas Färber
static int handle_intercept(S390CPU *cpu)
738 0e60a699 Alexander Graf
{
739 f7575c96 Andreas Färber
    CPUState *cs = CPU(cpu);
740 f7575c96 Andreas Färber
    struct kvm_run *run = cs->kvm_run;
741 0e60a699 Alexander Graf
    int icpt_code = run->s390_sieic.icptcode;
742 0e60a699 Alexander Graf
    int r = 0;
743 0e60a699 Alexander Graf
744 e67137c6 Peter Maydell
    DPRINTF("intercept: 0x%x (at 0x%lx)\n", icpt_code,
745 f7575c96 Andreas Färber
            (long)cs->kvm_run->psw_addr);
746 0e60a699 Alexander Graf
    switch (icpt_code) {
747 0e60a699 Alexander Graf
        case ICPT_INSTRUCTION:
748 d2ee7746 Thomas Huth
            handle_instruction(cpu, run);
749 0e60a699 Alexander Graf
            break;
750 0e60a699 Alexander Graf
        case ICPT_WAITPSW:
751 08eb8c85 Christian Borntraeger
            /* disabled wait, since enabled wait is handled in kernel */
752 08eb8c85 Christian Borntraeger
            if (s390_del_running_cpu(cpu) == 0) {
753 08eb8c85 Christian Borntraeger
                if (is_special_wait_psw(cs)) {
754 08eb8c85 Christian Borntraeger
                    qemu_system_shutdown_request();
755 08eb8c85 Christian Borntraeger
                } else {
756 08eb8c85 Christian Borntraeger
                    QObject *data;
757 08eb8c85 Christian Borntraeger
758 08eb8c85 Christian Borntraeger
                    data = qobject_from_jsonf("{ 'action': %s }", "pause");
759 08eb8c85 Christian Borntraeger
                    monitor_protocol_event(QEVENT_GUEST_PANICKED, data);
760 08eb8c85 Christian Borntraeger
                    qobject_decref(data);
761 08eb8c85 Christian Borntraeger
                    vm_stop(RUN_STATE_GUEST_PANICKED);
762 08eb8c85 Christian Borntraeger
                }
763 eca3ed03 Christian Borntraeger
            }
764 eca3ed03 Christian Borntraeger
            r = EXCP_HALTED;
765 eca3ed03 Christian Borntraeger
            break;
766 854e42f3 Christian Borntraeger
        case ICPT_CPU_STOP:
767 49e15878 Andreas Färber
            if (s390_del_running_cpu(cpu) == 0) {
768 854e42f3 Christian Borntraeger
                qemu_system_shutdown_request();
769 854e42f3 Christian Borntraeger
            }
770 854e42f3 Christian Borntraeger
            r = EXCP_HALTED;
771 0e60a699 Alexander Graf
            break;
772 0e60a699 Alexander Graf
        case ICPT_SOFT_INTERCEPT:
773 0e60a699 Alexander Graf
            fprintf(stderr, "KVM unimplemented icpt SOFT\n");
774 0e60a699 Alexander Graf
            exit(1);
775 0e60a699 Alexander Graf
            break;
776 0e60a699 Alexander Graf
        case ICPT_IO:
777 0e60a699 Alexander Graf
            fprintf(stderr, "KVM unimplemented icpt IO\n");
778 0e60a699 Alexander Graf
            exit(1);
779 0e60a699 Alexander Graf
            break;
780 0e60a699 Alexander Graf
        default:
781 0e60a699 Alexander Graf
            fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
782 0e60a699 Alexander Graf
            exit(1);
783 0e60a699 Alexander Graf
            break;
784 0e60a699 Alexander Graf
    }
785 0e60a699 Alexander Graf
786 0e60a699 Alexander Graf
    return r;
787 0e60a699 Alexander Graf
}
788 0e60a699 Alexander Graf
789 09b99878 Cornelia Huck
static int handle_tsch(S390CPU *cpu)
790 09b99878 Cornelia Huck
{
791 09b99878 Cornelia Huck
    CPUS390XState *env = &cpu->env;
792 09b99878 Cornelia Huck
    CPUState *cs = CPU(cpu);
793 09b99878 Cornelia Huck
    struct kvm_run *run = cs->kvm_run;
794 09b99878 Cornelia Huck
    int ret;
795 09b99878 Cornelia Huck
796 44c68de0 Dominik Dingel
    cpu_synchronize_state(cs);
797 3474b679 Jason J. Herne
798 09b99878 Cornelia Huck
    ret = ioinst_handle_tsch(env, env->regs[1], run->s390_tsch.ipb);
799 09b99878 Cornelia Huck
    if (ret >= 0) {
800 09b99878 Cornelia Huck
        /* Success; set condition code. */
801 09b99878 Cornelia Huck
        setcc(cpu, ret);
802 09b99878 Cornelia Huck
        ret = 0;
803 09b99878 Cornelia Huck
    } else if (ret < -1) {
804 09b99878 Cornelia Huck
        /*
805 09b99878 Cornelia Huck
         * Failure.
806 09b99878 Cornelia Huck
         * If an I/O interrupt had been dequeued, we have to reinject it.
807 09b99878 Cornelia Huck
         */
808 09b99878 Cornelia Huck
        if (run->s390_tsch.dequeued) {
809 09b99878 Cornelia Huck
            uint16_t subchannel_id = run->s390_tsch.subchannel_id;
810 09b99878 Cornelia Huck
            uint16_t subchannel_nr = run->s390_tsch.subchannel_nr;
811 09b99878 Cornelia Huck
            uint32_t io_int_parm = run->s390_tsch.io_int_parm;
812 09b99878 Cornelia Huck
            uint32_t io_int_word = run->s390_tsch.io_int_word;
813 09b99878 Cornelia Huck
            uint32_t type = ((subchannel_id & 0xff00) << 24) |
814 09b99878 Cornelia Huck
                ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
815 09b99878 Cornelia Huck
816 09b99878 Cornelia Huck
            kvm_s390_interrupt_internal(cpu, type,
817 09b99878 Cornelia Huck
                                        ((uint32_t)subchannel_id << 16)
818 09b99878 Cornelia Huck
                                        | subchannel_nr,
819 09b99878 Cornelia Huck
                                        ((uint64_t)io_int_parm << 32)
820 09b99878 Cornelia Huck
                                        | io_int_word, 1);
821 09b99878 Cornelia Huck
        }
822 09b99878 Cornelia Huck
        ret = 0;
823 09b99878 Cornelia Huck
    }
824 09b99878 Cornelia Huck
    return ret;
825 09b99878 Cornelia Huck
}
826 09b99878 Cornelia Huck
827 20d695a9 Andreas Färber
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
828 0e60a699 Alexander Graf
{
829 20d695a9 Andreas Färber
    S390CPU *cpu = S390_CPU(cs);
830 0e60a699 Alexander Graf
    int ret = 0;
831 0e60a699 Alexander Graf
832 0e60a699 Alexander Graf
    switch (run->exit_reason) {
833 0e60a699 Alexander Graf
        case KVM_EXIT_S390_SIEIC:
834 1bc22652 Andreas Färber
            ret = handle_intercept(cpu);
835 0e60a699 Alexander Graf
            break;
836 0e60a699 Alexander Graf
        case KVM_EXIT_S390_RESET:
837 add142e0 Jens Freimann
            qemu_system_reset_request();
838 0e60a699 Alexander Graf
            break;
839 09b99878 Cornelia Huck
        case KVM_EXIT_S390_TSCH:
840 09b99878 Cornelia Huck
            ret = handle_tsch(cpu);
841 09b99878 Cornelia Huck
            break;
842 0e60a699 Alexander Graf
        default:
843 0e60a699 Alexander Graf
            fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
844 0e60a699 Alexander Graf
            break;
845 0e60a699 Alexander Graf
    }
846 0e60a699 Alexander Graf
847 bb4ea393 Jan Kiszka
    if (ret == 0) {
848 bb4ea393 Jan Kiszka
        ret = EXCP_INTERRUPT;
849 bb4ea393 Jan Kiszka
    }
850 0e60a699 Alexander Graf
    return ret;
851 0e60a699 Alexander Graf
}
852 4513d923 Gleb Natapov
853 20d695a9 Andreas Färber
bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
854 4513d923 Gleb Natapov
{
855 4513d923 Gleb Natapov
    return true;
856 4513d923 Gleb Natapov
}
857 a1b87fe0 Jan Kiszka
858 20d695a9 Andreas Färber
int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
859 a1b87fe0 Jan Kiszka
{
860 a1b87fe0 Jan Kiszka
    return 1;
861 a1b87fe0 Jan Kiszka
}
862 a1b87fe0 Jan Kiszka
863 a1b87fe0 Jan Kiszka
int kvm_arch_on_sigbus(int code, void *addr)
864 a1b87fe0 Jan Kiszka
{
865 a1b87fe0 Jan Kiszka
    return 1;
866 a1b87fe0 Jan Kiszka
}
867 09b99878 Cornelia Huck
868 09b99878 Cornelia Huck
void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id,
869 09b99878 Cornelia Huck
                           uint16_t subchannel_nr, uint32_t io_int_parm,
870 09b99878 Cornelia Huck
                           uint32_t io_int_word)
871 09b99878 Cornelia Huck
{
872 09b99878 Cornelia Huck
    uint32_t type;
873 09b99878 Cornelia Huck
874 09b99878 Cornelia Huck
    type = ((subchannel_id & 0xff00) << 24) |
875 09b99878 Cornelia Huck
        ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
876 09b99878 Cornelia Huck
    kvm_s390_interrupt_internal(cpu, type,
877 09b99878 Cornelia Huck
                                ((uint32_t)subchannel_id << 16) | subchannel_nr,
878 09b99878 Cornelia Huck
                                ((uint64_t)io_int_parm << 32) | io_int_word, 1);
879 09b99878 Cornelia Huck
}
880 09b99878 Cornelia Huck
881 09b99878 Cornelia Huck
void kvm_s390_crw_mchk(S390CPU *cpu)
882 09b99878 Cornelia Huck
{
883 09b99878 Cornelia Huck
    kvm_s390_interrupt_internal(cpu, KVM_S390_MCHK, 1 << 28,
884 09b99878 Cornelia Huck
                                0x00400f1d40330000, 1);
885 09b99878 Cornelia Huck
}
886 09b99878 Cornelia Huck
887 09b99878 Cornelia Huck
void kvm_s390_enable_css_support(S390CPU *cpu)
888 09b99878 Cornelia Huck
{
889 09b99878 Cornelia Huck
    struct kvm_enable_cap cap = {};
890 09b99878 Cornelia Huck
    int r;
891 09b99878 Cornelia Huck
892 09b99878 Cornelia Huck
    /* Activate host kernel channel subsystem support. */
893 09b99878 Cornelia Huck
    cap.cap = KVM_CAP_S390_CSS_SUPPORT;
894 09b99878 Cornelia Huck
    r = kvm_vcpu_ioctl(CPU(cpu), KVM_ENABLE_CAP, &cap);
895 09b99878 Cornelia Huck
    assert(r == 0);
896 09b99878 Cornelia Huck
}
897 48475e14 Alexey Kardashevskiy
898 48475e14 Alexey Kardashevskiy
void kvm_arch_init_irq_routing(KVMState *s)
899 48475e14 Alexey Kardashevskiy
{
900 48475e14 Alexey Kardashevskiy
}
901 b4436a0b Cornelia Huck
902 cc3ac9c4 Cornelia Huck
int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
903 cc3ac9c4 Cornelia Huck
                                    int vq, bool assign)
904 b4436a0b Cornelia Huck
{
905 b4436a0b Cornelia Huck
    struct kvm_ioeventfd kick = {
906 b4436a0b Cornelia Huck
        .flags = KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY |
907 b4436a0b Cornelia Huck
        KVM_IOEVENTFD_FLAG_DATAMATCH,
908 cc3ac9c4 Cornelia Huck
        .fd = event_notifier_get_fd(notifier),
909 b4436a0b Cornelia Huck
        .datamatch = vq,
910 b4436a0b Cornelia Huck
        .addr = sch,
911 b4436a0b Cornelia Huck
        .len = 8,
912 b4436a0b Cornelia Huck
    };
913 b4436a0b Cornelia Huck
    if (!kvm_check_extension(kvm_state, KVM_CAP_IOEVENTFD)) {
914 b4436a0b Cornelia Huck
        return -ENOSYS;
915 b4436a0b Cornelia Huck
    }
916 b4436a0b Cornelia Huck
    if (!assign) {
917 b4436a0b Cornelia Huck
        kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
918 b4436a0b Cornelia Huck
    }
919 b4436a0b Cornelia Huck
    return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
920 b4436a0b Cornelia Huck
}