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