Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull first set of KVM updates from Paolo Bonzini: "PPC: - minor code cleanups x86: - PCID emulation and CR3 caching for shadow page tables - nested VMX live migration - nested VMCS shadowing - optimized IPI hypercall - some optimizations ARM will come next week" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (85 commits) kvm: x86: Set highest physical address bits in non-present/reserved SPTEs KVM/x86: Use CC_SET()/CC_OUT in arch/x86/kvm/vmx.c KVM: X86: Implement PV IPIs in linux guest KVM: X86: Add kvm hypervisor init time platform setup callback KVM: X86: Implement "send IPI" hypercall KVM/x86: Move X86_CR4_OSXSAVE check into kvm_valid_sregs() KVM: x86: Skip pae_root shadow allocation if tdp enabled KVM/MMU: Combine flushing remote tlb in mmu_set_spte() KVM: vmx: skip VMWRITE of HOST_{FS,GS}_BASE when possible KVM: vmx: skip VMWRITE of HOST_{FS,GS}_SEL when possible KVM: vmx: always initialize HOST_{FS,GS}_BASE to zero during setup KVM: vmx: move struct host_state usage to struct loaded_vmcs KVM: vmx: compute need to reload FS/GS/LDT on demand KVM: nVMX: remove a misleading comment regarding vmcs02 fields KVM: vmx: rename __vmx_load_host_state() and vmx_save_host_state() KVM: vmx: add dedicated utility to access guest's kernel_gs_base KVM: vmx: track host_state.loaded using a loaded_vmcs pointer KVM: vmx: refactor segmentation code in vmx_save_host_state() kvm: nVMX: Fix fault priority for VMX operations kvm: nVMX: Fix fault vector for VMX operation at CPL > 0 ...
This commit is contained in:
@@ -310,6 +310,7 @@ struct ms_hyperv_tsc_page {
|
||||
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
|
||||
|
||||
/* Nested features (CPUID 0x4000000A) EAX */
|
||||
#define HV_X64_NESTED_GUEST_MAPPING_FLUSH BIT(18)
|
||||
#define HV_X64_NESTED_MSR_BITMAP BIT(19)
|
||||
|
||||
struct hv_reenlightenment_control {
|
||||
@@ -351,6 +352,7 @@ struct hv_tsc_emulation_status {
|
||||
#define HVCALL_SEND_IPI_EX 0x0015
|
||||
#define HVCALL_POST_MESSAGE 0x005c
|
||||
#define HVCALL_SIGNAL_EVENT 0x005d
|
||||
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
|
||||
|
||||
#define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001
|
||||
#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12
|
||||
@@ -742,6 +744,12 @@ struct ipi_arg_ex {
|
||||
struct hv_vpset vp_set;
|
||||
};
|
||||
|
||||
/* HvFlushGuestPhysicalAddressSpace hypercalls */
|
||||
struct hv_guest_mapping_flush {
|
||||
u64 address_space;
|
||||
u64 flags;
|
||||
};
|
||||
|
||||
/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
|
||||
struct hv_tlb_flush {
|
||||
u64 address_space;
|
||||
|
@@ -55,6 +55,7 @@
|
||||
#define KVM_REQ_TRIPLE_FAULT KVM_ARCH_REQ(2)
|
||||
#define KVM_REQ_MMU_SYNC KVM_ARCH_REQ(3)
|
||||
#define KVM_REQ_CLOCK_UPDATE KVM_ARCH_REQ(4)
|
||||
#define KVM_REQ_LOAD_CR3 KVM_ARCH_REQ(5)
|
||||
#define KVM_REQ_EVENT KVM_ARCH_REQ(6)
|
||||
#define KVM_REQ_APF_HALT KVM_ARCH_REQ(7)
|
||||
#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(8)
|
||||
@@ -76,13 +77,13 @@
|
||||
#define KVM_REQ_HV_EXIT KVM_ARCH_REQ(21)
|
||||
#define KVM_REQ_HV_STIMER KVM_ARCH_REQ(22)
|
||||
#define KVM_REQ_LOAD_EOI_EXITMAP KVM_ARCH_REQ(23)
|
||||
#define KVM_REQ_GET_VMCS12_PAGES KVM_ARCH_REQ(24)
|
||||
|
||||
#define CR0_RESERVED_BITS \
|
||||
(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
|
||||
| X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
|
||||
| X86_CR0_NW | X86_CR0_CD | X86_CR0_PG))
|
||||
|
||||
#define CR3_PCID_INVD BIT_64(63)
|
||||
#define CR4_RESERVED_BITS \
|
||||
(~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
|
||||
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
|
||||
@@ -326,6 +327,16 @@ struct rsvd_bits_validate {
|
||||
u64 bad_mt_xwr;
|
||||
};
|
||||
|
||||
struct kvm_mmu_root_info {
|
||||
gpa_t cr3;
|
||||
hpa_t hpa;
|
||||
};
|
||||
|
||||
#define KVM_MMU_ROOT_INFO_INVALID \
|
||||
((struct kvm_mmu_root_info) { .cr3 = INVALID_PAGE, .hpa = INVALID_PAGE })
|
||||
|
||||
#define KVM_MMU_NUM_PREV_ROOTS 3
|
||||
|
||||
/*
|
||||
* x86 supports 4 paging modes (5-level 64-bit, 4-level 64-bit, 3-level 32-bit,
|
||||
* and 2-level 32-bit). The kvm_mmu structure abstracts the details of the
|
||||
@@ -345,7 +356,7 @@ struct kvm_mmu {
|
||||
struct x86_exception *exception);
|
||||
int (*sync_page)(struct kvm_vcpu *vcpu,
|
||||
struct kvm_mmu_page *sp);
|
||||
void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva);
|
||||
void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa);
|
||||
void (*update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
|
||||
u64 *spte, const void *pte);
|
||||
hpa_t root_hpa;
|
||||
@@ -354,6 +365,7 @@ struct kvm_mmu {
|
||||
u8 shadow_root_level;
|
||||
u8 ept_ad;
|
||||
bool direct_map;
|
||||
struct kvm_mmu_root_info prev_roots[KVM_MMU_NUM_PREV_ROOTS];
|
||||
|
||||
/*
|
||||
* Bitmap; bit set = permission fault
|
||||
@@ -978,6 +990,15 @@ struct kvm_x86_ops {
|
||||
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
|
||||
|
||||
void (*tlb_flush)(struct kvm_vcpu *vcpu, bool invalidate_gpa);
|
||||
int (*tlb_remote_flush)(struct kvm *kvm);
|
||||
|
||||
/*
|
||||
* Flush any TLB entries associated with the given GVA.
|
||||
* Does not need to flush GPA->HPA mappings.
|
||||
* Can potentially get non-canonical addresses through INVLPGs, which
|
||||
* the implementation may choose to ignore if appropriate.
|
||||
*/
|
||||
void (*tlb_flush_gva)(struct kvm_vcpu *vcpu, gva_t addr);
|
||||
|
||||
void (*run)(struct kvm_vcpu *vcpu);
|
||||
int (*handle_exit)(struct kvm_vcpu *vcpu);
|
||||
@@ -1090,6 +1111,14 @@ struct kvm_x86_ops {
|
||||
|
||||
void (*setup_mce)(struct kvm_vcpu *vcpu);
|
||||
|
||||
int (*get_nested_state)(struct kvm_vcpu *vcpu,
|
||||
struct kvm_nested_state __user *user_kvm_nested_state,
|
||||
unsigned user_data_size);
|
||||
int (*set_nested_state)(struct kvm_vcpu *vcpu,
|
||||
struct kvm_nested_state __user *user_kvm_nested_state,
|
||||
struct kvm_nested_state *kvm_state);
|
||||
void (*get_vmcs12_pages)(struct kvm_vcpu *vcpu);
|
||||
|
||||
int (*smi_allowed)(struct kvm_vcpu *vcpu);
|
||||
int (*pre_enter_smm)(struct kvm_vcpu *vcpu, char *smstate);
|
||||
int (*pre_leave_smm)(struct kvm_vcpu *vcpu, u64 smbase);
|
||||
@@ -1122,6 +1151,16 @@ static inline void kvm_arch_free_vm(struct kvm *kvm)
|
||||
return kvm_x86_ops->vm_free(kvm);
|
||||
}
|
||||
|
||||
#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLB
|
||||
static inline int kvm_arch_flush_remote_tlb(struct kvm *kvm)
|
||||
{
|
||||
if (kvm_x86_ops->tlb_remote_flush &&
|
||||
!kvm_x86_ops->tlb_remote_flush(kvm))
|
||||
return 0;
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
int kvm_mmu_module_init(void);
|
||||
void kvm_mmu_module_exit(void);
|
||||
|
||||
@@ -1273,6 +1312,10 @@ static inline int __kvm_irq_line_state(unsigned long *irq_state,
|
||||
return !!(*irq_state);
|
||||
}
|
||||
|
||||
#define KVM_MMU_ROOT_CURRENT BIT(0)
|
||||
#define KVM_MMU_ROOT_PREVIOUS(i) BIT(1+i)
|
||||
#define KVM_MMU_ROOTS_ALL (~0UL)
|
||||
|
||||
int kvm_pic_set_irq(struct kvm_pic *pic, int irq, int irq_source_id, int level);
|
||||
void kvm_pic_clear_all(struct kvm_pic *pic, int irq_source_id);
|
||||
|
||||
@@ -1284,7 +1327,7 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_load(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_free_roots(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, ulong roots_to_free);
|
||||
gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access,
|
||||
struct x86_exception *exception);
|
||||
gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
|
||||
@@ -1303,7 +1346,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u64 error_code,
|
||||
void *insn, int insn_len);
|
||||
void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
|
||||
void kvm_mmu_new_cr3(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t gva, unsigned long pcid);
|
||||
void kvm_mmu_new_cr3(struct kvm_vcpu *vcpu, gpa_t new_cr3, bool skip_tlb_flush);
|
||||
|
||||
void kvm_enable_tdp(void);
|
||||
void kvm_disable_tdp(void);
|
||||
@@ -1418,6 +1462,10 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
|
||||
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
|
||||
void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
|
||||
unsigned long ipi_bitmap_high, int min,
|
||||
unsigned long icr, int op_64_bit);
|
||||
|
||||
u64 kvm_get_arch_capabilities(void);
|
||||
void kvm_define_shared_msr(unsigned index, u32 msr);
|
||||
int kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
|
||||
|
@@ -347,6 +347,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
|
||||
void set_hv_tscchange_cb(void (*cb)(void));
|
||||
void clear_hv_tscchange_cb(void);
|
||||
void hyperv_stop_tsc_emulation(void);
|
||||
int hyperv_flush_guest_mapping(u64 as);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
void hv_apic_init(void);
|
||||
@@ -366,6 +367,7 @@ static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline int hyperv_flush_guest_mapping(u64 as) { return -1; }
|
||||
#endif /* CONFIG_HYPERV */
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
|
@@ -28,6 +28,20 @@ TRACE_EVENT(hyperv_mmu_flush_tlb_others,
|
||||
__entry->addr, __entry->end)
|
||||
);
|
||||
|
||||
TRACE_EVENT(hyperv_nested_flush_guest_mapping,
|
||||
TP_PROTO(u64 as, int ret),
|
||||
TP_ARGS(as, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u64, as)
|
||||
__field(int, ret)
|
||||
),
|
||||
TP_fast_assign(__entry->as = as;
|
||||
__entry->ret = ret;
|
||||
),
|
||||
TP_printk("address space %llx ret %d", __entry->as, __entry->ret)
|
||||
);
|
||||
|
||||
TRACE_EVENT(hyperv_send_ipi_mask,
|
||||
TP_PROTO(const struct cpumask *cpus,
|
||||
int vector),
|
||||
|
@@ -378,4 +378,41 @@ struct kvm_sync_regs {
|
||||
#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
|
||||
#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1)
|
||||
|
||||
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
|
||||
#define KVM_STATE_NESTED_RUN_PENDING 0x00000002
|
||||
|
||||
#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
|
||||
#define KVM_STATE_NESTED_SMM_VMXON 0x00000002
|
||||
|
||||
struct kvm_vmx_nested_state {
|
||||
__u64 vmxon_pa;
|
||||
__u64 vmcs_pa;
|
||||
|
||||
struct {
|
||||
__u16 flags;
|
||||
} smm;
|
||||
};
|
||||
|
||||
/* for KVM_CAP_NESTED_STATE */
|
||||
struct kvm_nested_state {
|
||||
/* KVM_STATE_* flags */
|
||||
__u16 flags;
|
||||
|
||||
/* 0 for VMX, 1 for SVM. */
|
||||
__u16 format;
|
||||
|
||||
/* 128 for SVM, 128 + VMCS size for VMX. */
|
||||
__u32 size;
|
||||
|
||||
union {
|
||||
/* VMXON, VMCS */
|
||||
struct kvm_vmx_nested_state vmx;
|
||||
|
||||
/* Pad the header to 128 bytes. */
|
||||
__u8 pad[120];
|
||||
};
|
||||
|
||||
__u8 data[0];
|
||||
};
|
||||
|
||||
#endif /* _ASM_X86_KVM_H */
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#define KVM_FEATURE_PV_UNHALT 7
|
||||
#define KVM_FEATURE_PV_TLB_FLUSH 9
|
||||
#define KVM_FEATURE_ASYNC_PF_VMEXIT 10
|
||||
#define KVM_FEATURE_PV_SEND_IPI 11
|
||||
|
||||
#define KVM_HINTS_REALTIME 0
|
||||
|
||||
|
Reference in New Issue
Block a user