Revision d362e757

b/cpu-all.h
375 375
#define CPU_INTERRUPT_TGT_INT_0   0x0100
376 376
#define CPU_INTERRUPT_TGT_INT_1   0x0400
377 377
#define CPU_INTERRUPT_TGT_INT_2   0x0800
378
#define CPU_INTERRUPT_TGT_INT_3   0x2000
378 379

  
379
/* First unused bit: 0x2000.  */
380
/* First unused bit: 0x4000.  */
380 381

  
381 382
/* The set of all bits that should be masked when single-stepping.  */
382 383
#define CPU_INTERRUPT_SSTEP_MASK \
b/hw/apic.h
18 18
uint8_t cpu_get_apic_tpr(DeviceState *s);
19 19
void apic_init_reset(DeviceState *s);
20 20
void apic_sipi(DeviceState *s);
21
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
22
                                   TPRAccess access);
21 23

  
22 24
/* pc.c */
23 25
int cpu_is_bsp(CPUState *env);
b/hw/apic_common.c
68 68
    return s ? s->tpr >> 4 : 0;
69 69
}
70 70

  
71
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
72
                                   TPRAccess access)
73
{
74
}
75

  
71 76
void apic_report_irq_delivered(int delivered)
72 77
{
73 78
    apic_irq_delivered += delivered;
b/hw/mc146818rtc.c
25 25
#include "qemu-timer.h"
26 26
#include "sysemu.h"
27 27
#include "pc.h"
28
#include "apic.h"
29 28
#include "isa.h"
30 29
#include "mc146818rtc.h"
31 30

  
31
#ifdef TARGET_I386
32
#include "apic.h"
33
#endif
34

  
32 35
//#define DEBUG_CMOS
33 36
//#define DEBUG_COALESCED
34 37

  
b/target-i386/cpu.h
482 482
#define CPU_INTERRUPT_VIRQ      CPU_INTERRUPT_TGT_INT_0
483 483
#define CPU_INTERRUPT_INIT      CPU_INTERRUPT_TGT_INT_1
484 484
#define CPU_INTERRUPT_SIPI      CPU_INTERRUPT_TGT_INT_2
485
#define CPU_INTERRUPT_TPR       CPU_INTERRUPT_TGT_INT_3
485 486

  
486 487

  
487 488
enum {
......
613 614

  
614 615
#define NB_MMU_MODES 2
615 616

  
617
typedef enum TPRAccess {
618
    TPR_ACCESS_READ,
619
    TPR_ACCESS_WRITE,
620
} TPRAccess;
621

  
616 622
typedef struct CPUX86State {
617 623
    /* standard registers */
618 624
    target_ulong regs[CPU_NB_REGS];
......
772 778
    XMMReg ymmh_regs[CPU_NB_REGS];
773 779

  
774 780
    uint64_t xcr0;
781

  
782
    TPRAccess tpr_access_type;
775 783
} CPUX86State;
776 784

  
777 785
CPUX86State *cpu_x86_init(const char *cpu_model);
......
1064 1072

  
1065 1073
uint32_t cpu_cc_compute_all(CPUState *env1, int op);
1066 1074

  
1075
void cpu_report_tpr_access(CPUState *env, TPRAccess access);
1076

  
1067 1077
#endif /* CPU_I386_H */
b/target-i386/helper.c
1189 1189
        }
1190 1190
    }
1191 1191
}
1192

  
1193
void cpu_report_tpr_access(CPUState *env, TPRAccess access)
1194
{
1195
    TranslationBlock *tb;
1196

  
1197
    if (kvm_enabled()) {
1198
        env->tpr_access_type = access;
1199

  
1200
        cpu_interrupt(env, CPU_INTERRUPT_TPR);
1201
    } else {
1202
        tb = tb_find_pc(env->mem_io_pc);
1203
        cpu_restore_state(tb, env, env->mem_io_pc);
1204

  
1205
        apic_handle_tpr_access_report(env->apic_state, env->eip, access);
1206
    }
1207
}
1192 1208
#endif /* !CONFIG_USER_ONLY */
1193 1209

  
1194 1210
static void mce_init(CPUX86State *cenv)
b/target-i386/kvm.c
1635 1635
    }
1636 1636

  
1637 1637
    if (!kvm_irqchip_in_kernel()) {
1638
        /* Force the VCPU out of its inner loop to process the INIT request */
1639
        if (env->interrupt_request & CPU_INTERRUPT_INIT) {
1638
        /* Force the VCPU out of its inner loop to process any INIT requests
1639
         * or pending TPR access reports. */
1640
        if (env->interrupt_request &
1641
            (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
1640 1642
            env->exit_request = 1;
1641 1643
        }
1642 1644

  
......
1730 1732
        kvm_cpu_synchronize_state(env);
1731 1733
        do_cpu_sipi(env);
1732 1734
    }
1735
    if (env->interrupt_request & CPU_INTERRUPT_TPR) {
1736
        env->interrupt_request &= ~CPU_INTERRUPT_TPR;
1737
        kvm_cpu_synchronize_state(env);
1738
        apic_handle_tpr_access_report(env->apic_state, env->eip,
1739
                                      env->tpr_access_type);
1740
    }
1733 1741

  
1734 1742
    return env->halted;
1735 1743
}
......
1746 1754
    return 0;
1747 1755
}
1748 1756

  
1757
static int kvm_handle_tpr_access(CPUState *env)
1758
{
1759
    struct kvm_run *run = env->kvm_run;
1760

  
1761
    apic_handle_tpr_access_report(env->apic_state, run->tpr_access.rip,
1762
                                  run->tpr_access.is_write ? TPR_ACCESS_WRITE
1763
                                                           : TPR_ACCESS_READ);
1764
    return 1;
1765
}
1766

  
1749 1767
int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
1750 1768
{
1751 1769
    static const uint8_t int3 = 0xcc;
......
1950 1968
    case KVM_EXIT_SET_TPR:
1951 1969
        ret = 0;
1952 1970
        break;
1971
    case KVM_EXIT_TPR_ACCESS:
1972
        ret = kvm_handle_tpr_access(env);
1973
        break;
1953 1974
    case KVM_EXIT_FAIL_ENTRY:
1954 1975
        code = run->fail_entry.hardware_entry_failure_reason;
1955 1976
        fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n",

Also available in: Unified diff