Commit ea8bc95f authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-nested-7.1' of https://github.com/kvm-x86/linux into HEAD

KVM nested SVM changes for 7.1 (with one common x86 fix)

 - To minimize the probability of corrupting guest state, defer KVM's
   non-architectural delivery of exception payloads (e.g. CR2 and DR6) until
   consumption of the payload is imminent, and force delivery of the payload
   in all paths where userspace saves relevant state.

 - Use vcpu->arch.cr2 when updating vmcb12's CR2 on nested #VMEXIT to fix a
   bug where L2's CR2 can get corrupted after a save/restore, e.g. if the VM
   is migrated while L2 is faulting in memory.

 - Fix a class of nSVM bugs where some fields written by the CPU are not
   synchronized from vmcb02 to cached vmcb12 after VMRUN, and so are not
   up-to-date when saved by KVM_GET_NESTED_STATE.

 - Fix a class of bugs where the ordering between KVM_SET_NESTED_STATE and
   KVM_SET_{S}REGS could cause vmcb02 to be incorrectly initialized after
   save+restore.

 - Add a variety of missing nSVM consistency checks.

 - Fix several bugs where KVM failed to correctly update VMCB fields on nested
   #VMEXIT.

 - Fix several bugs where KVM failed to correctly synthesize #UD or #GP for
   SVM-related instructions.

 - Add support for save+restore of virtualized LBRs (on SVM).

 - Refactor various helpers and macros to improve clarity and (hopefully) make
   the code easier to maintain.

 - Aggressively sanitize fields when copying from vmcb12 to guard against
   unintentionally allowing L1 to utilize yet-to-be-defined features.

 - Fix several bugs where KVM botched rAX legality checks when emulating SVM
   instructions.  Note, KVM is still flawed in that KVM doesn't address size
   prefix overrides for 64-bit guests; this should probably be documented as a
   KVM erratum.

 - Fail emulation of VMRUN/VMLOAD/VMSAVE if mapping vmcb12 fails instead of
   somewhat arbitrarily synthesizing #GP (i.e. don't bastardize AMD's already-
   sketchy behavior of generating #GP if for "unsupported" addresses).

 - Cache all used vmcb12 fields to further harden against TOCTOU bugs.
parents 1b3090da 052ca584
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1098,6 +1098,21 @@ struct kvm_vcpu_arch {
	 */
	bool pdptrs_from_userspace;

	/*
	 * Set if an emulated nested VM-Enter to L2 is pending completion.  KVM
	 * must not synthesize a VM-Exit to L1 before entering L2, as VM-Exits
	 * can only occur at instruction boundaries.  The only exception is
	 * VMX's "notify" exits, which exist in large part to break the CPU out
	 * of infinite ucode loops, but can corrupt vCPU state in the process!
	 *
	 * For all intents and purposes, this is a boolean, but it's tracked as
	 * a u8 so that KVM can detect when userspace may have stuffed vCPU
	 * state and generated an architecturally-impossible VM-Exit.
	 */
#define KVM_NESTED_RUN_PENDING			1
#define KVM_NESTED_RUN_PENDING_UNTRUSTED	2
	u8 nested_run_pending;

#if IS_ENABLED(CONFIG_HYPERV)
	hpa_t hv_root_tdp;
#endif
+13 −7
Original line number Diff line number Diff line
@@ -142,13 +142,13 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
	u64 exit_info_2;
	u32 exit_int_info;
	u32 exit_int_info_err;
	u64 nested_ctl;
	u64 misc_ctl;
	u64 avic_vapic_bar;
	u64 ghcb_gpa;
	u32 event_inj;
	u32 event_inj_err;
	u64 nested_cr3;
	u64 virt_ext;
	u64 misc_ctl2;
	u32 clean;
	u32 reserved_5;
	u64 next_rip;
@@ -182,6 +182,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define TLB_CONTROL_FLUSH_ASID 3
#define TLB_CONTROL_FLUSH_ASID_LOCAL 7

#define TLB_CONTROL_MASK GENMASK(2, 0)

#define ERAP_CONTROL_ALLOW_LARGER_RAP BIT(0)
#define ERAP_CONTROL_CLEAR_RAP BIT(1)

@@ -222,8 +224,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define X2APIC_MODE_SHIFT 30
#define X2APIC_MODE_MASK (1 << X2APIC_MODE_SHIFT)

#define LBR_CTL_ENABLE_MASK BIT_ULL(0)
#define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1)
#define SVM_INT_VECTOR_MASK GENMASK(7, 0)

#define SVM_INTERRUPT_SHADOW_MASK	BIT_ULL(0)
#define SVM_GUEST_INTERRUPT_MASK	BIT_ULL(1)
@@ -239,10 +240,12 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)

#define SVM_NESTED_CTL_NP_ENABLE	BIT(0)
#define SVM_NESTED_CTL_SEV_ENABLE	BIT(1)
#define SVM_NESTED_CTL_SEV_ES_ENABLE	BIT(2)
#define SVM_MISC_ENABLE_NP		BIT(0)
#define SVM_MISC_ENABLE_SEV		BIT(1)
#define SVM_MISC_ENABLE_SEV_ES	BIT(2)

#define SVM_MISC2_ENABLE_V_LBR	BIT_ULL(0)
#define SVM_MISC2_ENABLE_V_VMLOAD_VMSAVE	BIT_ULL(1)

#define SVM_TSC_RATIO_RSVD	0xffffff0000000000ULL
#define SVM_TSC_RATIO_MIN	0x0000000000000001ULL
@@ -636,6 +639,9 @@ static inline void __unused_size_checks(void)
#define SVM_EVTINJ_VALID (1 << 31)
#define SVM_EVTINJ_VALID_ERR (1 << 11)

#define SVM_EVTINJ_RESERVED_BITS ~(SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | \
				   SVM_EVTINJ_VALID_ERR | SVM_EVTINJ_VALID)

#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
#define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK

+1 −2
Original line number Diff line number Diff line
@@ -3887,8 +3887,7 @@ static int check_svme_pa(struct x86_emulate_ctxt *ctxt)
{
	u64 rax = reg_read(ctxt, VCPU_REGS_RAX);

	/* Valid physical address? */
	if (rax & 0xffff000000000000ULL)
	if (!ctxt->ops->page_address_valid(ctxt, rax))
		return emulate_gp(ctxt, 0);

	return check_svme(ctxt);
+0 −8
Original line number Diff line number Diff line
@@ -305,14 +305,6 @@ static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
{
	return false;
}
static inline bool kvm_hv_is_tlb_flush_hcall(struct kvm_vcpu *vcpu)
{
	return false;
}
static inline bool guest_hv_cpuid_has_l2_tlb_flush(struct kvm_vcpu *vcpu)
{
	return false;
}
static inline int kvm_hv_verify_vp_assist(struct kvm_vcpu *vcpu)
{
	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -245,6 +245,8 @@ struct x86_emulate_ops {

	bool (*is_canonical_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr,
				  unsigned int flags);

	bool (*page_address_valid)(struct x86_emulate_ctxt *ctxt, gpa_t gpa);
};

/* Type, address-of, and value of an instruction's operand. */
Loading