diff options
| -rw-r--r-- | arch/x86/kvm/vmx.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b23ecc04ca51..16f9373c01de 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "kvm_cache_regs.h" | 38 | #include "kvm_cache_regs.h" |
| 39 | #include "x86.h" | 39 | #include "x86.h" |
| 40 | 40 | ||
| 41 | #include <asm/asm.h> | ||
| 41 | #include <asm/cpu.h> | 42 | #include <asm/cpu.h> |
| 42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| 43 | #include <asm/desc.h> | 44 | #include <asm/desc.h> |
| @@ -1916,11 +1917,12 @@ static inline void __invvpid(int ext, u16 vpid, gva_t gva) | |||
| 1916 | u64 rsvd : 48; | 1917 | u64 rsvd : 48; |
| 1917 | u64 gva; | 1918 | u64 gva; |
| 1918 | } operand = { vpid, 0, gva }; | 1919 | } operand = { vpid, 0, gva }; |
| 1920 | bool error; | ||
| 1919 | 1921 | ||
| 1920 | asm volatile (__ex(ASM_VMX_INVVPID) | 1922 | asm volatile (__ex(ASM_VMX_INVVPID) CC_SET(na) |
| 1921 | /* CF==1 or ZF==1 --> rc = -1 */ | 1923 | : CC_OUT(na) (error) : "a"(&operand), "c"(ext) |
| 1922 | "; ja 1f ; ud2 ; 1:" | 1924 | : "memory"); |
| 1923 | : : "a"(&operand), "c"(ext) : "cc", "memory"); | 1925 | BUG_ON(error); |
| 1924 | } | 1926 | } |
| 1925 | 1927 | ||
| 1926 | static inline void __invept(int ext, u64 eptp, gpa_t gpa) | 1928 | static inline void __invept(int ext, u64 eptp, gpa_t gpa) |
| @@ -1928,11 +1930,12 @@ static inline void __invept(int ext, u64 eptp, gpa_t gpa) | |||
| 1928 | struct { | 1930 | struct { |
| 1929 | u64 eptp, gpa; | 1931 | u64 eptp, gpa; |
| 1930 | } operand = {eptp, gpa}; | 1932 | } operand = {eptp, gpa}; |
| 1933 | bool error; | ||
| 1931 | 1934 | ||
| 1932 | asm volatile (__ex(ASM_VMX_INVEPT) | 1935 | asm volatile (__ex(ASM_VMX_INVEPT) CC_SET(na) |
| 1933 | /* CF==1 or ZF==1 --> rc = -1 */ | 1936 | : CC_OUT(na) (error) : "a" (&operand), "c" (ext) |
| 1934 | "; ja 1f ; ud2 ; 1:\n" | 1937 | : "memory"); |
| 1935 | : : "a" (&operand), "c" (ext) : "cc", "memory"); | 1938 | BUG_ON(error); |
| 1936 | } | 1939 | } |
| 1937 | 1940 | ||
| 1938 | static struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) | 1941 | static struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) |
| @@ -1948,12 +1951,12 @@ static struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) | |||
| 1948 | static void vmcs_clear(struct vmcs *vmcs) | 1951 | static void vmcs_clear(struct vmcs *vmcs) |
| 1949 | { | 1952 | { |
| 1950 | u64 phys_addr = __pa(vmcs); | 1953 | u64 phys_addr = __pa(vmcs); |
| 1951 | u8 error; | 1954 | bool error; |
| 1952 | 1955 | ||
| 1953 | asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0" | 1956 | asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) CC_SET(na) |
| 1954 | : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) | 1957 | : CC_OUT(na) (error) : "a"(&phys_addr), "m"(phys_addr) |
| 1955 | : "cc", "memory"); | 1958 | : "memory"); |
| 1956 | if (error) | 1959 | if (unlikely(error)) |
| 1957 | printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", | 1960 | printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", |
| 1958 | vmcs, phys_addr); | 1961 | vmcs, phys_addr); |
| 1959 | } | 1962 | } |
| @@ -1970,15 +1973,15 @@ static inline void loaded_vmcs_init(struct loaded_vmcs *loaded_vmcs) | |||
| 1970 | static void vmcs_load(struct vmcs *vmcs) | 1973 | static void vmcs_load(struct vmcs *vmcs) |
| 1971 | { | 1974 | { |
| 1972 | u64 phys_addr = __pa(vmcs); | 1975 | u64 phys_addr = __pa(vmcs); |
| 1973 | u8 error; | 1976 | bool error; |
| 1974 | 1977 | ||
| 1975 | if (static_branch_unlikely(&enable_evmcs)) | 1978 | if (static_branch_unlikely(&enable_evmcs)) |
| 1976 | return evmcs_load(phys_addr); | 1979 | return evmcs_load(phys_addr); |
| 1977 | 1980 | ||
| 1978 | asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0" | 1981 | asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) CC_SET(na) |
| 1979 | : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) | 1982 | : CC_OUT(na) (error) : "a"(&phys_addr), "m"(phys_addr) |
| 1980 | : "cc", "memory"); | 1983 | : "memory"); |
| 1981 | if (error) | 1984 | if (unlikely(error)) |
| 1982 | printk(KERN_ERR "kvm: vmptrld %p/%llx failed\n", | 1985 | printk(KERN_ERR "kvm: vmptrld %p/%llx failed\n", |
| 1983 | vmcs, phys_addr); | 1986 | vmcs, phys_addr); |
| 1984 | } | 1987 | } |
| @@ -2203,10 +2206,10 @@ static noinline void vmwrite_error(unsigned long field, unsigned long value) | |||
| 2203 | 2206 | ||
| 2204 | static __always_inline void __vmcs_writel(unsigned long field, unsigned long value) | 2207 | static __always_inline void __vmcs_writel(unsigned long field, unsigned long value) |
| 2205 | { | 2208 | { |
| 2206 | u8 error; | 2209 | bool error; |
| 2207 | 2210 | ||
| 2208 | asm volatile (__ex(ASM_VMX_VMWRITE_RAX_RDX) "; setna %0" | 2211 | asm volatile (__ex(ASM_VMX_VMWRITE_RAX_RDX) CC_SET(na) |
| 2209 | : "=q"(error) : "a"(value), "d"(field) : "cc"); | 2212 | : CC_OUT(na) (error) : "a"(value), "d"(field)); |
| 2210 | if (unlikely(error)) | 2213 | if (unlikely(error)) |
| 2211 | vmwrite_error(field, value); | 2214 | vmwrite_error(field, value); |
| 2212 | } | 2215 | } |
