Commit d362e757 authored by Jan Kiszka's avatar Jan Kiszka Committed by Avi Kivity
Browse files

target-i386: Add infrastructure for reporting TPR MMIO accesses



This will allow the APIC core to file a TPR access report. Depending on
the accelerator and kernel irqchip mode, it will either be delivered
right away or queued for later reporting.

In TCG mode, we can restart the triggering instruction and can therefore
forward the event directly. KVM does not allows us to restart, so we
postpone the delivery of events recording in the user space APIC until
the current instruction is completed.

Note that KVM without in-kernel irqchip will report the address after
the instruction that triggered the access.

Signed-off-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent d798e974
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -375,8 +375,9 @@ DECLARE_TLS(CPUState *,cpu_single_env);
#define CPU_INTERRUPT_TGT_INT_0   0x0100
#define CPU_INTERRUPT_TGT_INT_1   0x0400
#define CPU_INTERRUPT_TGT_INT_2   0x0800
#define CPU_INTERRUPT_TGT_INT_3   0x2000

/* First unused bit: 0x2000.  */
/* First unused bit: 0x4000.  */

/* The set of all bits that should be masked when single-stepping.  */
#define CPU_INTERRUPT_SSTEP_MASK \
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ void cpu_set_apic_tpr(DeviceState *s, uint8_t val);
uint8_t cpu_get_apic_tpr(DeviceState *s);
void apic_init_reset(DeviceState *s);
void apic_sipi(DeviceState *s);
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
                                   TPRAccess access);

/* pc.c */
int cpu_is_bsp(CPUState *env);
+5 −0
Original line number Diff line number Diff line
@@ -68,6 +68,11 @@ uint8_t cpu_get_apic_tpr(DeviceState *d)
    return s ? s->tpr >> 4 : 0;
}

void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
                                   TPRAccess access)
{
}

void apic_report_irq_delivered(int delivered)
{
    apic_irq_delivered += delivered;
+4 −1
Original line number Diff line number Diff line
@@ -25,10 +25,13 @@
#include "qemu-timer.h"
#include "sysemu.h"
#include "pc.h"
#include "apic.h"
#include "isa.h"
#include "mc146818rtc.h"

#ifdef TARGET_I386
#include "apic.h"
#endif

//#define DEBUG_CMOS
//#define DEBUG_COALESCED

+10 −0
Original line number Diff line number Diff line
@@ -482,6 +482,7 @@
#define CPU_INTERRUPT_VIRQ      CPU_INTERRUPT_TGT_INT_0
#define CPU_INTERRUPT_INIT      CPU_INTERRUPT_TGT_INT_1
#define CPU_INTERRUPT_SIPI      CPU_INTERRUPT_TGT_INT_2
#define CPU_INTERRUPT_TPR       CPU_INTERRUPT_TGT_INT_3


enum {
@@ -613,6 +614,11 @@ typedef struct {

#define NB_MMU_MODES 2

typedef enum TPRAccess {
    TPR_ACCESS_READ,
    TPR_ACCESS_WRITE,
} TPRAccess;

typedef struct CPUX86State {
    /* standard registers */
    target_ulong regs[CPU_NB_REGS];
@@ -772,6 +778,8 @@ typedef struct CPUX86State {
    XMMReg ymmh_regs[CPU_NB_REGS];

    uint64_t xcr0;

    TPRAccess tpr_access_type;
} CPUX86State;

CPUX86State *cpu_x86_init(const char *cpu_model);
@@ -1064,4 +1072,6 @@ void svm_check_intercept(CPUState *env1, uint32_t type);

uint32_t cpu_cc_compute_all(CPUState *env1, int op);

void cpu_report_tpr_access(CPUState *env, TPRAccess access);

#endif /* CPU_I386_H */
Loading