On Fri, Oct 14, 2016 at 01:21:55PM +0200, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imamm...@redhat.com>
> ---
> v4:
>  - restore kvm_has_x2apic_api() and use it to avoid side-effects
>    of kvm_enable_x2apic(). x2APIC API will be enabled by iommu
>    if it's present or not enabled at all.
> v3:
>  - drop kvm_has_x2apic_api() and reuse kvm_enable_x2apic() instead
> ---
>  target-i386/kvm_i386.h |  1 +
>  hw/i386/kvm/apic.c     | 12 ++++++++++--
>  target-i386/kvm.c      | 13 ++++++++++---
>  3 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h
> index 5c369b1..7607929 100644
> --- a/target-i386/kvm_i386.h
> +++ b/target-i386/kvm_i386.h
> @@ -44,4 +44,5 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id);
>  void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
>  
>  bool kvm_enable_x2apic(void);
> +bool kvm_has_x2apic_api(void);
>  #endif
> diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
> index be55102..39b73e7 100644
> --- a/hw/i386/kvm/apic.c
> +++ b/hw/i386/kvm/apic.c
> @@ -34,7 +34,11 @@ static void kvm_put_apic_state(APICCommonState *s, struct 
> kvm_lapic_state *kapic
>      int i;
>  
>      memset(kapic, 0, sizeof(*kapic));
> -    kvm_apic_set_reg(kapic, 0x2, s->id << 24);
> +    if (kvm_has_x2apic_api() && s->apicbase & MSR_IA32_APICBASE_EXTD) {
> +        kvm_apic_set_reg(kapic, 0x2, s->initial_apic_id);

What happens if:

* x2apic is enabled on CPUID;
* guest sets MSR_IA32_APICBASE_EXTD; an
* the x2apic API is not enabled?

Does that mean kvm_{put,get}_apic_state() was already broken, or
is the x2apic ID translated to the old format by the kernel when
the x2apic API is disabled?

> +    } else {
> +        kvm_apic_set_reg(kapic, 0x2, s->id << 24);
> +    }
>      kvm_apic_set_reg(kapic, 0x8, s->tpr);
>      kvm_apic_set_reg(kapic, 0xd, s->log_dest << 24);
>      kvm_apic_set_reg(kapic, 0xe, s->dest_mode << 28 | 0x0fffffff);
> @@ -59,7 +63,11 @@ void kvm_get_apic_state(DeviceState *dev, struct 
> kvm_lapic_state *kapic)
>      APICCommonState *s = APIC_COMMON(dev);
>      int i, v;
>  
> -    s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
> +    if (kvm_has_x2apic_api() && s->apicbase & MSR_IA32_APICBASE_EXTD) {
> +        assert(kvm_apic_get_reg(kapic, 0x2) == s->initial_apic_id);
> +    } else {
> +        s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
> +    }
>      s->tpr = kvm_apic_get_reg(kapic, 0x8);
>      s->arb_id = kvm_apic_get_reg(kapic, 0x9);
>      s->log_dest = kvm_apic_get_reg(kapic, 0xd) >> 24;
[...]

-- 
Eduardo

Reply via email to