Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 106 additions & 8 deletions arch/x86/include/asm/hyperv-tlfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
/* Support for physical CPU dynamic partitioning events is available*/
#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE BIT(3)
/*
* Support for passing hypercall input parameter block via XMM
* Support for passing hypercall input and output parameter block via XMM
* registers is available
*/
#define HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE BIT(4)
Expand Down Expand Up @@ -387,9 +387,6 @@ struct hv_tsc_emulation_status {
#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12

/* Number of XMM registers used in hypercall input/output */
#define HV_HYPERCALL_MAX_XMM_REGISTERS 6

struct hv_nested_enlightenments_control {
struct {
__u32 directhypercall:1;
Expand All @@ -401,14 +398,39 @@ struct hv_nested_enlightenments_control {
} hypercallControls;
} __packed;

struct hv_vp_vtl_control {
__u32 vtl_entry_reason;

union {
__u8 as_u8;
struct {
__u8 vina_asserted:1;
__u8 reserved0:7;
};
};

__u8 reserved1[3];

union {
struct {
__u64 vtl_ret_x64rax;
__u64 vtl_ret_x64rcx;
};

struct {
__u32 vtl_return_x86_eax;
__u32 vtl_return_x86_ecx;
__u32 vtl_return_x86_edx;
__u32 reserved2;
};
};
};

/* Define virtual processor assist page structure. */
struct hv_vp_assist_page {
__u32 apic_assist;
__u32 reserved1;
__u32 vtl_entry_reason;
__u32 vtl_reserved;
__u64 vtl_ret_x64rax;
__u64 vtl_ret_x64rcx;
struct hv_vp_vtl_control vtl_control;
struct hv_nested_enlightenments_control nested_control;
__u8 enlighten_vmentry;
__u8 reserved2[7];
Expand Down Expand Up @@ -799,6 +821,82 @@ struct hv_get_vp_from_apic_id_in {
u32 apic_ids[];
} __packed;


/* struct hv_intercept_header::access_type_mask */
#define HV_INTERCEPT_ACCESS_MASK_NONE 0
#define HV_INTERCEPT_ACCESS_MASK_READ 1
#define HV_INTERCEPT_ACCESS_MASK_WRITE 2
#define HV_INTERCEPT_ACCESS_MASK_EXECUTE 4

/* struct hv_intercept_exception::cache_type */
#define HV_X64_CACHE_TYPE_UNCACHED 0
#define HV_X64_CACHE_TYPE_WRITECOMBINING 1
#define HV_X64_CACHE_TYPE_WRITETHROUGH 4
#define HV_X64_CACHE_TYPE_WRITEPROTECTED 5
#define HV_X64_CACHE_TYPE_WRITEBACK 6

/* Intecept message header */
struct hv_intercept_header {
__u32 vp_index;
__u8 instruction_length;
#define HV_INTERCEPT_ACCESS_READ 0
#define HV_INTERCEPT_ACCESS_WRITE 1
#define HV_INTERCEPT_ACCESS_EXECUTE 2
__u8 access_type_mask;
union {
__u16 as_u16;
struct {
__u16 cpl:2;
__u16 cr0_pe:1;
__u16 cr0_am:1;
__u16 efer_lma:1;
__u16 debug_active:1;
__u16 interruption_pending:1;
__u16 reserved:9;
};
} exec_state;
struct hv_x64_segment_register cs;
__u64 rip;
__u64 rflags;
} __packed;

union hv_x64_memory_access_info {
__u8 as_u8;
struct {
__u8 gva_valid:1;
__u8 _reserved:7;
};
};

struct hv_memory_intercept_message {
struct hv_intercept_header header;
__u32 cache_type;
__u8 instruction_byte_count;
union hv_x64_memory_access_info memory_access_info;
__u16 _reserved;
__u64 gva;
__u64 gpa;
__u8 instruction_bytes[16];
struct hv_x64_segment_register ds;
struct hv_x64_segment_register ss;
__u64 rax;
__u64 rcx;
__u64 rdx;
__u64 rbx;
__u64 rsp;
__u64 rbp;
__u64 rsi;
__u64 rdi;
__u64 r8;
__u64 r9;
__u64 r10;
__u64 r11;
__u64 r12;
__u64 r13;
__u64 r14;
__u64 r15;
} __packed;

#include <asm-generic/hyperv-tlfs.h>

#endif
26 changes: 25 additions & 1 deletion arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
KVM_ARCH_REQ_FLAGS(31, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_HV_TLB_FLUSH \
KVM_ARCH_REQ_FLAGS(32, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_HV_INJECT_INTERCEPT KVM_ARCH_REQ(33)

#define CR0_RESERVED_BITS \
(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
Expand Down Expand Up @@ -338,7 +339,8 @@ union kvm_mmu_page_role {
unsigned ad_disabled:1;
unsigned guest_mode:1;
unsigned passthrough:1;
unsigned :5;
unsigned vtl:4;
unsigned :1;

/*
* This is left at the top of the word so that
Expand Down Expand Up @@ -638,6 +640,13 @@ struct kvm_vcpu_hv_tlb_flush_fifo {
DECLARE_KFIFO(entries, u64, KVM_HV_TLB_FLUSH_FIFO_SIZE);
};

struct kvm_vcpu_hv_intercept_info {
struct kvm_vcpu *vcpu;
int type;
u64 gpa;
u8 access;
};

/* Hyper-V per vcpu emulation context */
struct kvm_vcpu_hv {
struct kvm_vcpu *vcpu;
Expand Down Expand Up @@ -672,6 +681,8 @@ struct kvm_vcpu_hv {
u64 vm_id;
u32 vp_id;
} nested;

struct kvm_vcpu_hv_intercept_info intercept_info;
};

struct kvm_hypervisor_cpuid {
Expand Down Expand Up @@ -966,6 +977,8 @@ struct kvm_vcpu_arch {
/* set at EPT violation at this point */
unsigned long exit_qualification;

u32 exit_instruction_len;

/* pv related host specific info */
struct {
bool pv_unhalted;
Expand Down Expand Up @@ -1105,6 +1118,9 @@ struct kvm_hv {
u64 hv_tsc_emulation_status;
u64 hv_invtsc_control;

union hv_register_vsm_code_page_offsets vsm_code_page_offsets32;
union hv_register_vsm_code_page_offsets vsm_code_page_offsets64;

/* How many vCPUs have VP index != vCPU index */
atomic_t num_mismatched_vp_indexes;

Expand All @@ -1116,6 +1132,9 @@ struct kvm_hv {

struct hv_partition_assist_pg *hv_pa_pg;
struct kvm_hv_syndbg hv_syndbg;

/* status of KVM_CAP_HYPERV_VSM */
bool hv_enable_vsm;
};

struct msr_bitmap_range {
Expand Down Expand Up @@ -1298,6 +1317,8 @@ struct kvm_arch {
struct rw_semaphore apicv_update_lock;
unsigned long apicv_inhibit_reasons;

uint64_t apic_id_mask_shift;

gpa_t wall_clock;

bool mwait_in_guest;
Expand Down Expand Up @@ -1495,6 +1516,7 @@ struct kvm_vcpu_stat {
u64 pf_fast;
u64 pf_mmio_spte_created;
u64 pf_guest;
u64 pf_user;
u64 tlb_flush;
u64 invlpg;

Expand Down Expand Up @@ -1981,6 +2003,8 @@ void kvm_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg);
void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);

void dump_ftrace_vmcs(struct kvm_vcpu *vcpu);
void dump_ftrace_vcpu_state(struct kvm_vcpu * vcpu);
int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
int reason, bool has_error_code, u32 error_code);

Expand Down
10 changes: 10 additions & 0 deletions arch/x86/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,4 +565,14 @@ struct kvm_pmu_event_filter {
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1

/* Partition-wide VSM state; for KVM_HV_GET/SET_VSM_STATE */
struct kvm_hv_vsm_state {
__u64 vsm_code_page_offsets64;
__u64 vsm_code_page_offsets32;
};

struct kvm_apic_id_mask {
__u64 width; /* mask width in bits, max 32 */
};

#endif /* _ASM_X86_KVM_H */
7 changes: 7 additions & 0 deletions arch/x86/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,11 @@ config KVM_PROVE_MMU
config KVM_EXTERNAL_WRITE_TRACKING
bool

config KVM_HYPERV_VSM
bool "KVM Hyper-V Virtual Secure Mode (VSM) support"
select KVM_GENERIC_MEMORY_ATTRIBUTES
help
Enables the KVM VSM device, and all dependencies necessary in to
emulate Hyper-V's VSM.

endif # VIRTUALIZATION
5 changes: 3 additions & 2 deletions arch/x86/kvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ include $(srctree)/virt/kvm/Makefile.kvm

kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \
i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \
mmu/spte.o
hyperv.o debugfs.o \
mmu/mmu.o mmu/page_track.o mmu/spte.o

ifdef CONFIG_HYPERV
kvm-y += kvm_onhyperv.o
Expand All @@ -21,6 +21,7 @@ endif
kvm-$(CONFIG_X86_64) += mmu/tdp_iter.o mmu/tdp_mmu.o
kvm-$(CONFIG_KVM_XEN) += xen.o
kvm-$(CONFIG_KVM_SMM) += smm.o
kvm-$(CONFIG_KVM_HYPERV_VSM) += hyperv-vsm.o

kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \
vmx/hyperv.o vmx/nested.o vmx/posted_intr.o
Expand Down
Loading