| @@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) · 2038 unmodified lines |
| 2039 | 2039 | } |
| 2040 | 2040 | } |
| 2041 | 2041 | |
| 2042 | +static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic) |
| 2043 | +{ |
| 2044 | + struct kvm *kvm = apic->vcpu->kvm; |
| 2045 | + |
| 2046 | + if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm)) |
| 2047 | + return; |
| 2048 | + |
| 2049 | + if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id) |
| 2050 | + return; |
| 2051 | + |
| 2052 | + kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); |
| 2053 | +} |
| 2054 | + |
| 2042 | 2055 | static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) |
| 2043 | 2056 | { |
| 2044 | 2057 | int ret = 0; |
| @@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) · 2 unmodified lines |
| 2047 | 2060 | |
| 2048 | 2061 | switch (reg) { |
| 2049 | 2062 | case APIC_ID: /* Local APIC ID */ |
| 2050 | | − if (!apic_x2apic_mode(apic)) |
| 2063 | + if (!apic_x2apic_mode(apic)) { |
| 2051 | 2064 | kvm_apic_set_xapic_id(apic, val >> 24); |
| 2052 | | − else |
| 2065 | + kvm_lapic_xapic_id_updated(apic); |
| 2066 | + } else { |
| 2053 | 2067 | ret = 1; |
| 2068 | + } |
| 2054 | 2069 | break; |
| 2055 | 2070 | |
| 2056 | 2071 | case APIC_TASKPRI: |
| @@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) · 279 unmodified lines |
| 2336 | 2351 | MSR_IA32_APICBASE_BASE; |
| 2337 | 2352 | |
| 2338 | 2353 | if ((value & MSR_IA32_APICBASE_ENABLE) && |
| 2339 | | − apic->base_address != APIC_DEFAULT_PHYS_BASE) |
| 2340 | | − pr_warn_once("APIC base relocation is unsupported by KVM"); |
| 2354 | + apic->base_address != APIC_DEFAULT_PHYS_BASE) { |
| 2355 | + kvm_set_apicv_inhibit(apic->vcpu->kvm, |
| 2356 | + APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); |
| 2357 | + } |
| 2341 | 2358 | } |
| 2342 | 2359 | |
| 2343 | 2360 | void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) |
| @@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu, · 304 unmodified lines |
| 2648 | 2665 | icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); |
| 2649 | 2666 | __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); |
| 2650 | 2667 | } |
| 2668 | + } else { |
| 2669 | + kvm_lapic_xapic_id_updated(vcpu->arch.apic); |
| 2651 | 2670 | } |
| 2652 | 2671 | |
| 2653 | 2672 | return 0; |