linux/arch/x86/kvm/x86.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef ARCH_X86_KVM_X86_H
   3#define ARCH_X86_KVM_X86_H
   4
   5#include <linux/kvm_host.h>
   6#include <asm/pvclock.h>
   7#include "kvm_cache_regs.h"
   8
   9#define KVM_DEFAULT_PLE_GAP             128
  10#define KVM_VMX_DEFAULT_PLE_WINDOW      4096
  11#define KVM_DEFAULT_PLE_WINDOW_GROW     2
  12#define KVM_DEFAULT_PLE_WINDOW_SHRINK   0
  13#define KVM_VMX_DEFAULT_PLE_WINDOW_MAX  UINT_MAX
  14#define KVM_SVM_DEFAULT_PLE_WINDOW_MAX  USHRT_MAX
  15#define KVM_SVM_DEFAULT_PLE_WINDOW      3000
  16
  17static inline unsigned int __grow_ple_window(unsigned int val,
  18                unsigned int base, unsigned int modifier, unsigned int max)
  19{
  20        u64 ret = val;
  21
  22        if (modifier < 1)
  23                return base;
  24
  25        if (modifier < base)
  26                ret *= modifier;
  27        else
  28                ret += modifier;
  29
  30        return min(ret, (u64)max);
  31}
  32
  33static inline unsigned int __shrink_ple_window(unsigned int val,
  34                unsigned int base, unsigned int modifier, unsigned int min)
  35{
  36        if (modifier < 1)
  37                return base;
  38
  39        if (modifier < base)
  40                val /= modifier;
  41        else
  42                val -= modifier;
  43
  44        return max(val, min);
  45}
  46
  47#define MSR_IA32_CR_PAT_DEFAULT  0x0007040600070406ULL
  48
  49static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
  50{
  51        vcpu->arch.exception.pending = false;
  52        vcpu->arch.exception.injected = false;
  53}
  54
  55static inline void kvm_queue_interrupt(struct kvm_vcpu *vcpu, u8 vector,
  56        bool soft)
  57{
  58        vcpu->arch.interrupt.injected = true;
  59        vcpu->arch.interrupt.soft = soft;
  60        vcpu->arch.interrupt.nr = vector;
  61}
  62
  63static inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
  64{
  65        vcpu->arch.interrupt.injected = false;
  66}
  67
  68static inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu)
  69{
  70        return vcpu->arch.exception.injected || vcpu->arch.interrupt.injected ||
  71                vcpu->arch.nmi_injected;
  72}
  73
  74static inline bool kvm_exception_is_soft(unsigned int nr)
  75{
  76        return (nr == BP_VECTOR) || (nr == OF_VECTOR);
  77}
  78
  79static inline bool is_protmode(struct kvm_vcpu *vcpu)
  80{
  81        return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
  82}
  83
  84static inline int is_long_mode(struct kvm_vcpu *vcpu)
  85{
  86#ifdef CONFIG_X86_64
  87        return vcpu->arch.efer & EFER_LMA;
  88#else
  89        return 0;
  90#endif
  91}
  92
  93static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
  94{
  95        int cs_db, cs_l;
  96
  97        if (!is_long_mode(vcpu))
  98                return false;
  99        kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 100        return cs_l;
 101}
 102
 103static inline bool is_la57_mode(struct kvm_vcpu *vcpu)
 104{
 105#ifdef CONFIG_X86_64
 106        return (vcpu->arch.efer & EFER_LMA) &&
 107                 kvm_read_cr4_bits(vcpu, X86_CR4_LA57);
 108#else
 109        return 0;
 110#endif
 111}
 112
 113static inline bool x86_exception_has_error_code(unsigned int vector)
 114{
 115        static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) |
 116                        BIT(NP_VECTOR) | BIT(SS_VECTOR) | BIT(GP_VECTOR) |
 117                        BIT(PF_VECTOR) | BIT(AC_VECTOR);
 118
 119        return (1U << vector) & exception_has_error_code;
 120}
 121
 122static inline bool mmu_is_nested(struct kvm_vcpu *vcpu)
 123{
 124        return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu;
 125}
 126
 127static inline int is_pae(struct kvm_vcpu *vcpu)
 128{
 129        return kvm_read_cr4_bits(vcpu, X86_CR4_PAE);
 130}
 131
 132static inline int is_pse(struct kvm_vcpu *vcpu)
 133{
 134        return kvm_read_cr4_bits(vcpu, X86_CR4_PSE);
 135}
 136
 137static inline int is_paging(struct kvm_vcpu *vcpu)
 138{
 139        return likely(kvm_read_cr0_bits(vcpu, X86_CR0_PG));
 140}
 141
 142static inline u32 bit(int bitno)
 143{
 144        return 1 << (bitno & 31);
 145}
 146
 147static inline u8 vcpu_virt_addr_bits(struct kvm_vcpu *vcpu)
 148{
 149        return kvm_read_cr4_bits(vcpu, X86_CR4_LA57) ? 57 : 48;
 150}
 151
 152static inline u8 ctxt_virt_addr_bits(struct x86_emulate_ctxt *ctxt)
 153{
 154        return (ctxt->ops->get_cr(ctxt, 4) & X86_CR4_LA57) ? 57 : 48;
 155}
 156
 157static inline u64 get_canonical(u64 la, u8 vaddr_bits)
 158{
 159        return ((int64_t)la << (64 - vaddr_bits)) >> (64 - vaddr_bits);
 160}
 161
 162static inline bool is_noncanonical_address(u64 la, struct kvm_vcpu *vcpu)
 163{
 164#ifdef CONFIG_X86_64
 165        return get_canonical(la, vcpu_virt_addr_bits(vcpu)) != la;
 166#else
 167        return false;
 168#endif
 169}
 170
 171static inline bool emul_is_noncanonical_address(u64 la,
 172                                                struct x86_emulate_ctxt *ctxt)
 173{
 174#ifdef CONFIG_X86_64
 175        return get_canonical(la, ctxt_virt_addr_bits(ctxt)) != la;
 176#else
 177        return false;
 178#endif
 179}
 180
 181static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
 182                                        gva_t gva, gfn_t gfn, unsigned access)
 183{
 184        /*
 185         * If this is a shadow nested page table, the "GVA" is
 186         * actually a nGPA.
 187         */
 188        vcpu->arch.mmio_gva = mmu_is_nested(vcpu) ? 0 : gva & PAGE_MASK;
 189        vcpu->arch.access = access;
 190        vcpu->arch.mmio_gfn = gfn;
 191        vcpu->arch.mmio_gen = kvm_memslots(vcpu->kvm)->generation;
 192}
 193
 194static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)
 195{
 196        return vcpu->arch.mmio_gen == kvm_memslots(vcpu->kvm)->generation;
 197}
 198
 199/*
 200 * Clear the mmio cache info for the given gva. If gva is MMIO_GVA_ANY, we
 201 * clear all mmio cache info.
 202 */
 203#define MMIO_GVA_ANY (~(gva_t)0)
 204
 205static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
 206{
 207        if (gva != MMIO_GVA_ANY && vcpu->arch.mmio_gva != (gva & PAGE_MASK))
 208                return;
 209
 210        vcpu->arch.mmio_gva = 0;
 211}
 212
 213static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
 214{
 215        if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gva &&
 216              vcpu->arch.mmio_gva == (gva & PAGE_MASK))
 217                return true;
 218
 219        return false;
 220}
 221
 222static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
 223{
 224        if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gfn &&
 225              vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT)
 226                return true;
 227
 228        return false;
 229}
 230
 231static inline unsigned long kvm_register_readl(struct kvm_vcpu *vcpu,
 232                                               enum kvm_reg reg)
 233{
 234        unsigned long val = kvm_register_read(vcpu, reg);
 235
 236        return is_64_bit_mode(vcpu) ? val : (u32)val;
 237}
 238
 239static inline void kvm_register_writel(struct kvm_vcpu *vcpu,
 240                                       enum kvm_reg reg,
 241                                       unsigned long val)
 242{
 243        if (!is_64_bit_mode(vcpu))
 244                val = (u32)val;
 245        return kvm_register_write(vcpu, reg, val);
 246}
 247
 248static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk)
 249{
 250        return !(kvm->arch.disabled_quirks & quirk);
 251}
 252
 253void kvm_set_pending_timer(struct kvm_vcpu *vcpu);
 254int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
 255
 256void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
 257u64 get_kvmclock_ns(struct kvm *kvm);
 258
 259int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
 260        gva_t addr, void *val, unsigned int bytes,
 261        struct x86_exception *exception);
 262
 263int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu,
 264        gva_t addr, void *val, unsigned int bytes,
 265        struct x86_exception *exception);
 266
 267int handle_ud(struct kvm_vcpu *vcpu);
 268
 269void kvm_vcpu_mtrr_init(struct kvm_vcpu *vcpu);
 270u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn);
 271bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 272int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 273int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 274bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
 275                                          int page_num);
 276bool kvm_vector_hashing_enabled(void);
 277int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
 278                            int emulation_type, void *insn, int insn_len);
 279
 280#define KVM_SUPPORTED_XCR0     (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
 281                                | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
 282                                | XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
 283                                | XFEATURE_MASK_PKRU)
 284extern u64 host_xcr0;
 285
 286extern u64 kvm_supported_xcr0(void);
 287
 288extern unsigned int min_timer_period_us;
 289
 290extern unsigned int lapic_timer_advance_ns;
 291
 292extern bool enable_vmware_backdoor;
 293
 294extern struct static_key kvm_no_apic_vcpu;
 295
 296static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
 297{
 298        return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
 299                                   vcpu->arch.virtual_tsc_shift);
 300}
 301
 302/* Same "calling convention" as do_div:
 303 * - divide (n << 32) by base
 304 * - put result in n
 305 * - return remainder
 306 */
 307#define do_shl32_div32(n, base)                                 \
 308        ({                                                      \
 309            u32 __quot, __rem;                                  \
 310            asm("divl %2" : "=a" (__quot), "=d" (__rem)         \
 311                        : "rm" (base), "0" (0), "1" ((u32) n)); \
 312            n = __quot;                                         \
 313            __rem;                                              \
 314         })
 315
 316static inline bool kvm_mwait_in_guest(struct kvm *kvm)
 317{
 318        return kvm->arch.mwait_in_guest;
 319}
 320
 321static inline bool kvm_hlt_in_guest(struct kvm *kvm)
 322{
 323        return kvm->arch.hlt_in_guest;
 324}
 325
 326static inline bool kvm_pause_in_guest(struct kvm *kvm)
 327{
 328        return kvm->arch.pause_in_guest;
 329}
 330
 331DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 332
 333static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
 334{
 335        __this_cpu_write(current_vcpu, vcpu);
 336}
 337
 338static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 339{
 340        __this_cpu_write(current_vcpu, NULL);
 341}
 342
 343#endif
 344