Gleb Natapov wrote on 2013-01-17:
> On Wed, Jan 16, 2013 at 06:21:11PM +0800, Yang Zhang wrote:
>> From: Yang Zhang <[email protected]>
>> @@ -6103,6 +6206,53 @@ static void update_cr8_intercept(struct kvm_vcpu
> *vcpu, int tpr, int irr)
>>      vmcs_write32(TPR_THRESHOLD, irr);
>>  }
>> +static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool
>> set) +{ +    u32 exec_control, sec_exec_control; +   int msr; +      struct
>> vcpu_vmx *vmx = to_vmx(vcpu); + +    /* There is not point to enable
>> virtualize x2apic without enable +    * apicv*/ +    if
>> (!cpu_has_vmx_virtualize_x2apic_mode() || !enable_apicv_reg) +               
>> return;
>> + +  if (set) { +            exec_control =
>> vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); +            /* virtualize x2apic 
>> mode
>> relies on tpr shadow */ +            if (!(exec_control & 
>> CPU_BASED_TPR_SHADOW))
>> +                    return; +       } + +   sec_exec_control =
>> vmcs_read32(SECONDARY_VM_EXEC_CONTROL); + +  if (set) {
>> +            sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
>> +            sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; +    
>> } else
>> { +          sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; +   
>>         if
>> (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) +                  
>> sec_exec_control
>> |= +                                 
>> SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; +      }
>> +    vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control); + +  if
>> (set) { +            for (msr = 0x800; msr <= 0x8ff; msr++)
>> +                    vmx_intercept_for_msr_read_x2apic(msr, false); + +      
>>         /* According
>> SDM, in x2apic mode, the whole id reg is used. +              * But in KVM, 
>> it
>> only use the highest eight bits. Need to +            * intercept it */
>> +            vmx_intercept_for_msr_read_x2apic(0x802, true); +               
>> /* TMCCT */
>> +            vmx_intercept_for_msr_read_x2apic(0x839, true); +               
>> /* TPR */
>> +            vmx_intercept_for_msr_write_x2apic(0x808, false); +     }
> Do it during vmx init, not here. Here you only need to call
> vmx_set_msr_bitmap().
Sure. It is more reasonable. 

>> +    vmx_set_msr_bitmap(vcpu);
>> +}
>> +
>>  static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) {        u32
>>  exit_intr_info; @@ -7366,6 +7516,7 @@ static struct kvm_x86_ops
>>  vmx_x86_ops = {     .enable_nmi_window = enable_nmi_window,
>>      .enable_irq_window = enable_irq_window,         .update_cr8_intercept =
>>  update_cr8_intercept,
>> +    .set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode,
>> 
>>      .set_tss_addr = vmx_set_tss_addr,       .get_tdp_level = get_ept_level, 
>> @@
>>  -7419,11 +7570,19 @@ static int __init vmx_init(void)       if
>>  (!vmx_msr_bitmap_legacy)            goto out1;
>> +    vmx_msr_bitmap_legacy_x2apic =
>> +                            (unsigned long *)__get_free_page(GFP_KERNEL);
>> +    if (!vmx_msr_bitmap_legacy_x2apic)
>> +            goto out2;
>> 
>>      vmx_msr_bitmap_longmode = (unsigned long
>>  *)__get_free_page(GFP_KERNEL);      if (!vmx_msr_bitmap_longmode)
>> -            goto out2;
>> +            goto out3;
>> 
>> +    vmx_msr_bitmap_longmode_x2apic =
>> +                            (unsigned long *)__get_free_page(GFP_KERNEL);
>> +    if (!vmx_msr_bitmap_longmode_x2apic)
>> +            goto out4;
>> 
>>      /*       * Allow direct access to the PC debug port (it is often used 
>> for
>>  I/O @@ -7456,6 +7615,11 @@ static int __init vmx_init(void)
>>      vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
>>      vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
>> +    memcpy(vmx_msr_bitmap_legacy_x2apic,
>> +                    vmx_msr_bitmap_legacy, PAGE_SIZE);
>> +    memcpy(vmx_msr_bitmap_longmode_x2apic,
>> +                    vmx_msr_bitmap_longmode, PAGE_SIZE);
>> +
>>      if (enable_ept) {
>>              kvm_mmu_set_mask_ptes(0ull,
>>                      (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
>> @@ -7468,8 +7632,10 @@ static int __init vmx_init(void)
>> 
>>      return 0;
>> -out3:
>> +out4:
>>      free_page((unsigned long)vmx_msr_bitmap_longmode);
>> +out3:
>> +    free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
>>  out2:
>>      free_page((unsigned long)vmx_msr_bitmap_legacy);
>>  out1:
>> @@ -7481,6 +7647,8 @@ out:
>> 
>>  static void __exit vmx_exit(void)
>>  {
>> +    free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
>> +    free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
>>      free_page((unsigned long)vmx_msr_bitmap_legacy);
>>      free_page((unsigned long)vmx_msr_bitmap_longmode);
>>      free_page((unsigned long)vmx_io_bitmap_b);
>> --
>> 1.7.1
> 
> --
>                       Gleb.


Best regards,
Yang


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to