diff options
Diffstat (limited to 'drivers/kvm/vmx.c')
| -rw-r--r-- | drivers/kvm/vmx.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index c07178e61122..fbbf9d6b299f 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
| @@ -371,10 +371,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
| 371 | data = vmcs_read32(GUEST_SYSENTER_CS); | 371 | data = vmcs_read32(GUEST_SYSENTER_CS); |
| 372 | break; | 372 | break; |
| 373 | case MSR_IA32_SYSENTER_EIP: | 373 | case MSR_IA32_SYSENTER_EIP: |
| 374 | data = vmcs_read32(GUEST_SYSENTER_EIP); | 374 | data = vmcs_readl(GUEST_SYSENTER_EIP); |
| 375 | break; | 375 | break; |
| 376 | case MSR_IA32_SYSENTER_ESP: | 376 | case MSR_IA32_SYSENTER_ESP: |
| 377 | data = vmcs_read32(GUEST_SYSENTER_ESP); | 377 | data = vmcs_readl(GUEST_SYSENTER_ESP); |
| 378 | break; | 378 | break; |
| 379 | default: | 379 | default: |
| 380 | msr = find_msr_entry(vcpu, msr_index); | 380 | msr = find_msr_entry(vcpu, msr_index); |
| @@ -412,10 +412,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | |||
| 412 | vmcs_write32(GUEST_SYSENTER_CS, data); | 412 | vmcs_write32(GUEST_SYSENTER_CS, data); |
| 413 | break; | 413 | break; |
| 414 | case MSR_IA32_SYSENTER_EIP: | 414 | case MSR_IA32_SYSENTER_EIP: |
| 415 | vmcs_write32(GUEST_SYSENTER_EIP, data); | 415 | vmcs_writel(GUEST_SYSENTER_EIP, data); |
| 416 | break; | 416 | break; |
| 417 | case MSR_IA32_SYSENTER_ESP: | 417 | case MSR_IA32_SYSENTER_ESP: |
| 418 | vmcs_write32(GUEST_SYSENTER_ESP, data); | 418 | vmcs_writel(GUEST_SYSENTER_ESP, data); |
| 419 | break; | 419 | break; |
| 420 | case MSR_IA32_TIME_STAMP_COUNTER: | 420 | case MSR_IA32_TIME_STAMP_COUNTER: |
| 421 | guest_write_tsc(data); | 421 | guest_write_tsc(data); |
| @@ -618,7 +618,7 @@ static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) | |||
| 618 | { | 618 | { |
| 619 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; | 619 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; |
| 620 | 620 | ||
| 621 | if (vmcs_readl(sf->base) == save->base) { | 621 | if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) { |
| 622 | vmcs_write16(sf->selector, save->selector); | 622 | vmcs_write16(sf->selector, save->selector); |
| 623 | vmcs_writel(sf->base, save->base); | 623 | vmcs_writel(sf->base, save->base); |
| 624 | vmcs_write32(sf->limit, save->limit); | 624 | vmcs_write32(sf->limit, save->limit); |
| @@ -1888,6 +1888,27 @@ again: | |||
| 1888 | [cr2]"i"(offsetof(struct kvm_vcpu, cr2)) | 1888 | [cr2]"i"(offsetof(struct kvm_vcpu, cr2)) |
| 1889 | : "cc", "memory" ); | 1889 | : "cc", "memory" ); |
| 1890 | 1890 | ||
| 1891 | /* | ||
| 1892 | * Reload segment selectors ASAP. (it's needed for a functional | ||
| 1893 | * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64 | ||
| 1894 | * relies on having 0 in %gs for the CPU PDA to work.) | ||
| 1895 | */ | ||
| 1896 | if (fs_gs_ldt_reload_needed) { | ||
| 1897 | load_ldt(ldt_sel); | ||
| 1898 | load_fs(fs_sel); | ||
| 1899 | /* | ||
| 1900 | * If we have to reload gs, we must take care to | ||
| 1901 | * preserve our gs base. | ||
| 1902 | */ | ||
| 1903 | local_irq_disable(); | ||
| 1904 | load_gs(gs_sel); | ||
| 1905 | #ifdef CONFIG_X86_64 | ||
| 1906 | wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); | ||
| 1907 | #endif | ||
| 1908 | local_irq_enable(); | ||
| 1909 | |||
| 1910 | reload_tss(); | ||
| 1911 | } | ||
| 1891 | ++kvm_stat.exits; | 1912 | ++kvm_stat.exits; |
| 1892 | 1913 | ||
| 1893 | save_msrs(vcpu->guest_msrs, NR_BAD_MSRS); | 1914 | save_msrs(vcpu->guest_msrs, NR_BAD_MSRS); |
| @@ -1905,22 +1926,6 @@ again: | |||
| 1905 | kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR); | 1926 | kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR); |
| 1906 | r = 0; | 1927 | r = 0; |
| 1907 | } else { | 1928 | } else { |
| 1908 | if (fs_gs_ldt_reload_needed) { | ||
| 1909 | load_ldt(ldt_sel); | ||
| 1910 | load_fs(fs_sel); | ||
| 1911 | /* | ||
| 1912 | * If we have to reload gs, we must take care to | ||
| 1913 | * preserve our gs base. | ||
| 1914 | */ | ||
| 1915 | local_irq_disable(); | ||
| 1916 | load_gs(gs_sel); | ||
| 1917 | #ifdef CONFIG_X86_64 | ||
| 1918 | wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); | ||
| 1919 | #endif | ||
| 1920 | local_irq_enable(); | ||
| 1921 | |||
| 1922 | reload_tss(); | ||
| 1923 | } | ||
| 1924 | /* | 1929 | /* |
| 1925 | * Profile KVM exit RIPs: | 1930 | * Profile KVM exit RIPs: |
| 1926 | */ | 1931 | */ |
