Revision 0e607a80
b/target-i386/cpu.h | ||
---|---|---|
691 | 691 |
MTRRVar mtrr_var[8]; |
692 | 692 |
|
693 | 693 |
/* For KVM */ |
694 |
uint64_t interrupt_bitmap[256 / 64]; |
|
695 | 694 |
uint32_t mp_state; |
695 |
int32_t interrupt_injected; |
|
696 | 696 |
|
697 | 697 |
/* in order to simplify APIC support, we leave this pointer to the |
698 | 698 |
user */ |
... | ... | |
709 | 709 |
uint16_t fpus_vmstate; |
710 | 710 |
uint16_t fptag_vmstate; |
711 | 711 |
uint16_t fpregs_format_vmstate; |
712 |
int32_t pending_irq_vmstate; |
|
713 | 712 |
} CPUX86State; |
714 | 713 |
|
715 | 714 |
CPUX86State *cpu_x86_init(const char *cpu_model); |
b/target-i386/kvm.c | ||
---|---|---|
23 | 23 |
#include "kvm.h" |
24 | 24 |
#include "cpu.h" |
25 | 25 |
#include "gdbstub.h" |
26 |
#include "host-utils.h" |
|
26 | 27 |
|
27 | 28 |
//#define DEBUG_KVM |
28 | 29 |
|
... | ... | |
223 | 224 |
|
224 | 225 |
void kvm_arch_reset_vcpu(CPUState *env) |
225 | 226 |
{ |
227 |
env->interrupt_injected = -1; |
|
226 | 228 |
} |
227 | 229 |
|
228 | 230 |
static int kvm_has_msr_star(CPUState *env) |
... | ... | |
411 | 413 |
{ |
412 | 414 |
struct kvm_sregs sregs; |
413 | 415 |
|
414 |
memcpy(sregs.interrupt_bitmap, |
|
415 |
env->interrupt_bitmap, |
|
416 |
sizeof(sregs.interrupt_bitmap)); |
|
416 |
memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); |
|
417 |
if (env->interrupt_injected >= 0) { |
|
418 |
sregs.interrupt_bitmap[env->interrupt_injected / 64] |= |
|
419 |
(uint64_t)1 << (env->interrupt_injected % 64); |
|
420 |
} |
|
417 | 421 |
|
418 | 422 |
if ((env->eflags & VM_MASK)) { |
419 | 423 |
set_v8086_seg(&sregs.cs, &env->segs[R_CS]); |
... | ... | |
520 | 524 |
{ |
521 | 525 |
struct kvm_sregs sregs; |
522 | 526 |
uint32_t hflags; |
523 |
int ret; |
|
527 |
int bit, i, ret;
|
|
524 | 528 |
|
525 | 529 |
ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); |
526 | 530 |
if (ret < 0) |
527 | 531 |
return ret; |
528 | 532 |
|
529 |
memcpy(env->interrupt_bitmap, |
|
530 |
sregs.interrupt_bitmap, |
|
531 |
sizeof(sregs.interrupt_bitmap)); |
|
533 |
/* There can only be one pending IRQ set in the bitmap at a time, so try |
|
534 |
to find it and save its number instead (-1 for none). */ |
|
535 |
env->interrupt_injected = -1; |
|
536 |
for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) { |
|
537 |
if (sregs.interrupt_bitmap[i]) { |
|
538 |
bit = ctz64(sregs.interrupt_bitmap[i]); |
|
539 |
env->interrupt_injected = i * 64 + bit; |
|
540 |
break; |
|
541 |
} |
|
542 |
} |
|
532 | 543 |
|
533 | 544 |
get_seg(&env->segs[R_CS], &sregs.cs); |
534 | 545 |
get_seg(&env->segs[R_DS], &sregs.ds); |
b/target-i386/machine.c | ||
---|---|---|
2 | 2 |
#include "hw/boards.h" |
3 | 3 |
#include "hw/pc.h" |
4 | 4 |
#include "hw/isa.h" |
5 |
#include "host-utils.h" |
|
6 | 5 |
|
7 | 6 |
#include "exec-all.h" |
8 | 7 |
#include "kvm.h" |
... | ... | |
320 | 319 |
static void cpu_pre_save(void *opaque) |
321 | 320 |
{ |
322 | 321 |
CPUState *env = opaque; |
323 |
int i, bit;
|
|
322 |
int i; |
|
324 | 323 |
|
325 | 324 |
cpu_synchronize_state(env); |
326 | 325 |
|
... | ... | |
336 | 335 |
#else |
337 | 336 |
env->fpregs_format_vmstate = 1; |
338 | 337 |
#endif |
339 |
|
|
340 |
/* There can only be one pending IRQ set in the bitmap at a time, so try |
|
341 |
to find it and save its number instead (-1 for none). */ |
|
342 |
env->pending_irq_vmstate = -1; |
|
343 |
for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) { |
|
344 |
if (env->interrupt_bitmap[i]) { |
|
345 |
bit = ctz64(env->interrupt_bitmap[i]); |
|
346 |
env->pending_irq_vmstate = i * 64 + bit; |
|
347 |
break; |
|
348 |
} |
|
349 |
} |
|
350 | 338 |
} |
351 | 339 |
|
352 | 340 |
static int cpu_pre_load(void *opaque) |
... | ... | |
375 | 363 |
for (i = 0; i < 4; i++) |
376 | 364 |
hw_breakpoint_insert(env, i); |
377 | 365 |
|
378 |
if (version_id >= 9) { |
|
379 |
memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap)); |
|
380 |
if (env->pending_irq_vmstate >= 0) { |
|
381 |
env->interrupt_bitmap[env->pending_irq_vmstate / 64] |= |
|
382 |
(uint64_t)1 << (env->pending_irq_vmstate % 64); |
|
383 |
} |
|
384 |
} |
|
385 |
|
|
386 | 366 |
tlb_flush(env, 1); |
387 | 367 |
return 0; |
388 | 368 |
} |
... | ... | |
465 | 445 |
VMSTATE_UINT64_V(mtrr_deftype, CPUState, 8), |
466 | 446 |
VMSTATE_MTRR_VARS(mtrr_var, CPUState, 8, 8), |
467 | 447 |
/* KVM-related states */ |
468 |
VMSTATE_INT32_V(pending_irq_vmstate, CPUState, 9),
|
|
448 |
VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
|
|
469 | 449 |
VMSTATE_UINT32_V(mp_state, CPUState, 9), |
470 | 450 |
VMSTATE_UINT64_V(tsc, CPUState, 9), |
471 | 451 |
/* MCE */ |
Also available in: Unified diff