Revision 81635574 target-arm/kvm.c

b/target-arm/kvm.c
43 43
int kvm_arch_init_vcpu(CPUState *cs)
44 44
{
45 45
    struct kvm_vcpu_init init;
46
    int ret;
47
    uint64_t v;
48
    struct kvm_one_reg r;
46 49

  
47 50
    init.target = KVM_ARM_TARGET_CORTEX_A15;
48 51
    memset(init.features, 0, sizeof(init.features));
49
    return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
52
    ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
53
    if (ret) {
54
        return ret;
55
    }
56
    /* Query the kernel to make sure it supports 32 VFP
57
     * registers: QEMU's "cortex-a15" CPU is always a
58
     * VFP-D32 core. The simplest way to do this is just
59
     * to attempt to read register d31.
60
     */
61
    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
62
    r.addr = (uintptr_t)(&v);
63
    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
64
    if (ret == ENOENT) {
65
        return EINVAL;
66
    }
67
    return ret;
50 68
}
51 69

  
52 70
typedef struct Reg {
......
72 90
        offsetof(CPUARMState, QEMUFIELD)         \
73 91
    }
74 92

  
93
#define VFPSYSREG(R)                                       \
94
    {                                                      \
95
        KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \
96
        KVM_REG_ARM_VFP_##R,                               \
97
        offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R])      \
98
    }
99

  
75 100
static const Reg regs[] = {
76 101
    /* R0_usr .. R14_usr */
77 102
    COREREG(usr_regs.uregs[0], regs[0]),
......
119 144
    CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */
120 145
    CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */
121 146
    CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */
147
    /* VFP system registers */
148
    VFPSYSREG(FPSID),
149
    VFPSYSREG(MVFR1),
150
    VFPSYSREG(MVFR0),
151
    VFPSYSREG(FPEXC),
152
    VFPSYSREG(FPINST),
153
    VFPSYSREG(FPINST2),
122 154
};
123 155

  
124 156
int kvm_arch_put_registers(CPUState *cs, int level)
......
128 160
    struct kvm_one_reg r;
129 161
    int mode, bn;
130 162
    int ret, i;
131
    uint32_t cpsr;
163
    uint32_t cpsr, fpscr;
132 164
    uint64_t ttbr;
133 165

  
134 166
    /* Make sure the banked regs are properly set */
......
179 211
        (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
180 212
    r.addr = (uintptr_t)(&ttbr);
181 213
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
214
    if (ret) {
215
        return ret;
216
    }
217

  
218
    /* VFP registers */
219
    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
220
    for (i = 0; i < 32; i++) {
221
        r.addr = (uintptr_t)(&env->vfp.regs[i]);
222
        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
223
        if (ret) {
224
            return ret;
225
        }
226
        r.id++;
227
    }
228

  
229
    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
230
        KVM_REG_ARM_VFP_FPSCR;
231
    fpscr = vfp_get_fpscr(env);
232
    r.addr = (uintptr_t)&fpscr;
233
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
182 234

  
183 235
    return ret;
184 236
}
......
190 242
    struct kvm_one_reg r;
191 243
    int mode, bn;
192 244
    int ret, i;
193
    uint32_t cpsr;
245
    uint32_t cpsr, fpscr;
194 246
    uint64_t ttbr;
195 247

  
196 248
    for (i = 0; i < ARRAY_SIZE(regs); i++) {
......
255 307
    env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
256 308
    env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
257 309

  
310
    /* VFP registers */
311
    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
312
    for (i = 0; i < 32; i++) {
313
        r.addr = (uintptr_t)(&env->vfp.regs[i]);
314
        ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
315
        if (ret) {
316
            return ret;
317
        }
318
        r.id++;
319
    }
320

  
321
    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
322
        KVM_REG_ARM_VFP_FPSCR;
323
    r.addr = (uintptr_t)&fpscr;
324
    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
325
    if (ret) {
326
        return ret;
327
    }
328
    vfp_set_fpscr(env, fpscr);
329

  
258 330
    return 0;
259 331
}
260 332

  

Also available in: Unified diff