kvm: x86: Add user space part for in-kernel APIC

This introduces the alternative APIC device which makes use of KVM's
in-kernel device model. External NMI injection via LINT1 is emulated by
checking the current state of the in-kernel APIC, only injecting a NMI
into the VCPU if LINT1 is unmasked and configured to DM_NMI.

MSI is not yet supported, so we disable this when the in-kernel model is
in use.

CC: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
Jan Kiszka 2011-10-16 13:23:26 +02:00
parent 9b5b76d449
commit 680c1c6fd7
5 changed files with 191 additions and 6 deletions

View file

@ -1337,6 +1337,36 @@ static int kvm_get_mp_state(CPUState *env)
return 0;
}
static int kvm_get_apic(CPUState *env)
{
DeviceState *apic = env->apic_state;
struct kvm_lapic_state kapic;
int ret;
if (apic && kvm_enabled() && kvm_irqchip_in_kernel()) {
ret = kvm_vcpu_ioctl(env, KVM_GET_LAPIC, &kapic);
if (ret < 0) {
return ret;
}
kvm_get_apic_state(apic, &kapic);
}
return 0;
}
static int kvm_put_apic(CPUState *env)
{
DeviceState *apic = env->apic_state;
struct kvm_lapic_state kapic;
if (apic && kvm_enabled() && kvm_irqchip_in_kernel()) {
kvm_put_apic_state(apic, &kapic);
return kvm_vcpu_ioctl(env, KVM_SET_LAPIC, &kapic);
}
return 0;
}
static int kvm_put_vcpu_events(CPUState *env, int level)
{
struct kvm_vcpu_events events;
@ -1510,6 +1540,10 @@ int kvm_arch_put_registers(CPUState *env, int level)
if (ret < 0) {
return ret;
}
ret = kvm_put_apic(env);
if (ret < 0) {
return ret;
}
}
ret = kvm_put_vcpu_events(env, level);
if (ret < 0) {
@ -1557,6 +1591,10 @@ int kvm_arch_get_registers(CPUState *env)
if (ret < 0) {
return ret;
}
ret = kvm_get_apic(env);
if (ret < 0) {
return ret;
}
ret = kvm_get_vcpu_events(env);
if (ret < 0) {
return ret;