}
if (!kvm_irqchip_in_kernel()) {
- /* Force the VCPU out of its inner loop to process the INIT request */
- if (env->interrupt_request & CPU_INTERRUPT_INIT) {
+ /* Force the VCPU out of its inner loop to process any INIT requests
+ * or pending TPR access reports. */
+ if (env->interrupt_request &
+ (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
env->exit_request = 1;
}
kvm_cpu_synchronize_state(env);
do_cpu_sipi(env);
}
+ if (env->interrupt_request & CPU_INTERRUPT_TPR) {
+ env->interrupt_request &= ~CPU_INTERRUPT_TPR;
+ kvm_cpu_synchronize_state(env);
+ apic_handle_tpr_access_report(env->apic_state, env->eip,
+ env->tpr_access_type);
+ }
return env->halted;
}
return 0;
}
+static int kvm_handle_tpr_access(CPUState *env)
+{
+ struct kvm_run *run = env->kvm_run;
+
+ apic_handle_tpr_access_report(env->apic_state, run->tpr_access.rip,
+ run->tpr_access.is_write ? TPR_ACCESS_WRITE
+ : TPR_ACCESS_READ);
+ return 1;
+}
+
int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
{
static const uint8_t int3 = 0xcc;
case KVM_EXIT_SET_TPR:
ret = 0;
break;
+ case KVM_EXIT_TPR_ACCESS:
+ ret = kvm_handle_tpr_access(env);
+ break;
case KVM_EXIT_FAIL_ENTRY:
code = run->fail_entry.hardware_entry_failure_reason;
fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n",