|
@@ -1344,9 +1344,8 @@ EXPORT_SYMBOL_GPL(kvm_lapic_reg_read);
|
|
|
|
|
|
static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
|
|
|
{
|
|
|
- return kvm_apic_hw_enabled(apic) &&
|
|
|
- addr >= apic->base_address &&
|
|
|
- addr < apic->base_address + LAPIC_MMIO_LENGTH;
|
|
|
+ return addr >= apic->base_address &&
|
|
|
+ addr < apic->base_address + LAPIC_MMIO_LENGTH;
|
|
|
}
|
|
|
|
|
|
static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
|
|
@@ -1358,6 +1357,15 @@ static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
|
|
|
if (!apic_mmio_in_range(apic, address))
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
+ if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) {
|
|
|
+ if (!kvm_check_has_quirk(vcpu->kvm,
|
|
|
+ KVM_X86_QUIRK_LAPIC_MMIO_HOLE))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ memset(data, 0xff, len);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
kvm_lapic_reg_read(apic, offset, len, data);
|
|
|
|
|
|
return 0;
|
|
@@ -1917,6 +1925,14 @@ static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
|
|
|
if (!apic_mmio_in_range(apic, address))
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
+ if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) {
|
|
|
+ if (!kvm_check_has_quirk(vcpu->kvm,
|
|
|
+ KVM_X86_QUIRK_LAPIC_MMIO_HOLE))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* APIC register must be aligned on 128-bits boundary.
|
|
|
* 32/64/128 bits registers must be accessed thru 32 bits.
|