aboutsummaryrefslogtreecommitdiff
path: root/hw/kvm/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kvm/apic.c')
-rw-r--r--hw/kvm/apic.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c
index 5bb0a4b9fd..9ca68f81aa 100644
--- a/hw/kvm/apic.c
+++ b/hw/kvm/apic.c
@@ -92,6 +92,35 @@ static void kvm_apic_set_tpr(APICCommonState *s, uint8_t val)
s->tpr = (val & 0x0f) << 4;
}
+static uint8_t kvm_apic_get_tpr(APICCommonState *s)
+{
+ return s->tpr >> 4;
+}
+
+static void kvm_apic_enable_tpr_reporting(APICCommonState *s, bool enable)
+{
+ struct kvm_tpr_access_ctl ctl = {
+ .enabled = enable
+ };
+
+ kvm_vcpu_ioctl(s->cpu_env, KVM_TPR_ACCESS_REPORTING, &ctl);
+}
+
+static void kvm_apic_vapic_base_update(APICCommonState *s)
+{
+ struct kvm_vapic_addr vapid_addr = {
+ .vapic_addr = s->vapic_paddr,
+ };
+ int ret;
+
+ ret = kvm_vcpu_ioctl(s->cpu_env, KVM_SET_VAPIC_ADDR, &vapid_addr);
+ if (ret < 0) {
+ fprintf(stderr, "KVM: setting VAPIC address failed (%s)\n",
+ strerror(-ret));
+ abort();
+ }
+}
+
static void do_inject_external_nmi(void *data)
{
APICCommonState *s = data;
@@ -129,6 +158,9 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
k->init = kvm_apic_init;
k->set_base = kvm_apic_set_base;
k->set_tpr = kvm_apic_set_tpr;
+ k->get_tpr = kvm_apic_get_tpr;
+ k->enable_tpr_reporting = kvm_apic_enable_tpr_reporting;
+ k->vapic_base_update = kvm_apic_vapic_base_update;
k->external_nmi = kvm_apic_external_nmi;
}