All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zeng Guang <guang.zeng@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
	Sean Christopherson <seanjc@google.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	H Peter Anvin <hpa@zytor.com>,
	kvm@vger.kernel.org
Cc: x86@kernel.org, linux-kernel@vger.kernel.org,
	Zeng Guang <guang.zeng@intel.com>
Subject: [PATCH v1 5/6] KVM: x86: LASS protection on KVM emulation
Date: Thu,  1 Jun 2023 22:23:08 +0800	[thread overview]
Message-ID: <20230601142309.6307-6-guang.zeng@intel.com> (raw)
In-Reply-To: <20230601142309.6307-1-guang.zeng@intel.com>

Do LASS violation check for instructions emulated by KVM. Note that for
instructions executed in the guest directly, hardware will perform the
check.

Not all instruction emulation leads to accesses to guest linear addresses
because 1) some instructions like CPUID, RDMSR, don't take memory as
operands 2) instruction fetch in most cases is already done inside the
guest.

Four cases in which KVM uses a linear address to access guest memory:
- KVM emulates instruction fetches or data accesses
- KVM emulates implicit data access to a system data structure
- VMX instruction emulation
- SGX ENCLS instruction emulation

LASS violation check applies to these linear addresses so as to enforce
mode-based protections as hardware behaves.

As exceptions, the target memory address of emulation of invlpg, branch
and call instructions doesn't require LASS violation check.

Signed-off-by: Zeng Guang <guang.zeng@intel.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
---
 arch/x86/kvm/emulate.c    | 30 ++++++++++++++++++++++++++++--
 arch/x86/kvm/vmx/nested.c |  3 +++
 arch/x86/kvm/vmx/sgx.c    |  4 ++++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9508836e8a35..ed5191fa2079 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -698,6 +698,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 	u8  va_bits;
 	bool fetch = !!(flags & X86EMUL_F_FETCH);
 	bool write = !!(flags & X86EMUL_F_WRITE);
+	u64 access = fetch ? PFERR_FETCH_MASK : 0;
 
 	la = seg_base(ctxt, addr.seg) + addr.ea;
 	*max_size = 0;
@@ -743,6 +744,10 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 		}
 		break;
 	}
+
+	if (ctxt->ops->check_lass(ctxt, access, *linear, flags))
+		goto bad;
+
 	if (la & (insn_alignment(ctxt, size) - 1))
 		return emulate_gp(ctxt, 0);
 	return X86EMUL_CONTINUE;
@@ -774,7 +779,11 @@ static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
 	unsigned max_size;
 	struct segmented_address addr = { .seg = VCPU_SREG_CS,
 					   .ea = dst };
-	u32 flags = X86EMUL_F_FETCH;
+	/*
+	 * LASS doesn't apply to addresses that specify the targets of jump and
+	 * call instructions.
+	 */
+	u32 flags = X86EMUL_F_FETCH | X86EMUL_F_SKIPLASS;
 
 	if (ctxt->op_bytes != sizeof(unsigned long))
 		addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
@@ -853,6 +862,13 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
 static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear,
 			      void *data, unsigned size)
 {
+	if (ctxt->ops->check_lass(ctxt, PFERR_IMPLICIT_ACCESS, linear, 0)) {
+		ctxt->exception.vector = GP_VECTOR;
+		ctxt->exception.error_code = 0;
+		ctxt->exception.error_code_valid = true;
+		return X86EMUL_PROPAGATE_FAULT;
+	}
+
 	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true);
 }
 
@@ -860,6 +876,13 @@ static int linear_write_system(struct x86_emulate_ctxt *ctxt,
 			       ulong linear, void *data,
 			       unsigned int size)
 {
+	if (ctxt->ops->check_lass(ctxt, PFERR_IMPLICIT_ACCESS, linear, 0)) {
+		ctxt->exception.vector = GP_VECTOR;
+		ctxt->exception.error_code = 0;
+		ctxt->exception.error_code_valid = true;
+		return X86EMUL_PROPAGATE_FAULT;
+	}
+
 	return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true);
 }
 
@@ -3448,8 +3471,11 @@ static int em_invlpg(struct x86_emulate_ctxt *ctxt)
 {
 	int rc;
 	ulong linear;
+	unsigned max_size;
 
-	rc = linearize(ctxt, ctxt->src.addr.mem, 1, false, &linear);
+	/* LASS doesn't apply to the memory address for invlpg */
+	rc = __linearize(ctxt, ctxt->src.addr.mem, &max_size, 1,
+			 X86EMUL_F_SKIPLASS, ctxt->mode, &linear);
 	if (rc == X86EMUL_CONTINUE)
 		ctxt->ops->invlpg(ctxt, linear);
 	/* Disable writeback. */
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index e35cf0bd0df9..bb1c3fa13c13 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4986,6 +4986,9 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,
 		 * destination for long mode!
 		 */
 		exn = is_noncanonical_address(*ret, vcpu);
+
+		if (!exn)
+			exn = vmx_check_lass(vcpu, 0, *ret, 0);
 	} else {
 		/*
 		 * When not in long mode, the virtual/linear address is
diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c
index 2261b684a7d4..3825275827eb 100644
--- a/arch/x86/kvm/vmx/sgx.c
+++ b/arch/x86/kvm/vmx/sgx.c
@@ -46,6 +46,10 @@ static int sgx_get_encls_gva(struct kvm_vcpu *vcpu, unsigned long offset,
 			((s.base != 0 || s.limit != 0xffffffff) &&
 			(((u64)*gva + size - 1) > s.limit + 1));
 	}
+
+	if (!fault && is_long_mode(vcpu))
+		fault = vmx_check_lass(vcpu, 0, *gva, 0);
+
 	if (fault)
 		kvm_inject_gp(vcpu, 0);
 	return fault ? -EINVAL : 0;
-- 
2.27.0


  parent reply	other threads:[~2023-06-01 15:06 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-01 14:23 [PATCH v1 0/6] LASS KVM virtualization support Zeng Guang
2023-06-01 14:23 ` [PATCH v1 1/6] KVM: x86: Consolidate flags for __linearize() Zeng Guang
2023-06-27 17:40   ` Sean Christopherson
2023-06-28  5:13     ` Binbin Wu
2023-06-28  7:27     ` Zeng Guang
2023-06-01 14:23 ` [PATCH v1 2/6] KVM: x86: Virtualize CR4.LASS Zeng Guang
2023-06-05  1:57   ` Binbin Wu
2023-06-06  2:57     ` Zeng Guang
2023-06-27 17:43   ` Sean Christopherson
2023-06-28  8:19     ` Zeng Guang
2023-08-16 22:16   ` Sean Christopherson
2023-06-01 14:23 ` [PATCH v1 3/6] KVM: VMX: Add new ops in kvm_x86_ops for LASS violation check Zeng Guang
2023-06-05  3:31   ` Binbin Wu
2023-06-05 12:53     ` Zhi Wang
2023-06-06  2:57       ` Binbin Wu
2023-06-06  3:53         ` Zhi Wang
2023-06-07  6:28     ` Zeng Guang
2023-06-05  3:47   ` Chao Gao
2023-06-06  6:22     ` Zeng Guang
2023-06-05 14:07   ` Yuan Yao
2023-06-06  3:08     ` Zeng Guang
2023-06-27 18:26   ` Sean Christopherson
2023-06-27 22:45     ` Sean Christopherson
2023-06-30 18:50     ` Zeng Guang
2023-06-01 14:23 ` [PATCH v1 4/6] KVM: x86: Add emulator helper " Zeng Guang
2023-06-27 18:28   ` Sean Christopherson
2023-06-29 15:06     ` Zeng Guang
2023-06-01 14:23 ` Zeng Guang [this message]
2023-06-06  4:20   ` [PATCH v1 5/6] KVM: x86: LASS protection on KVM emulation Binbin Wu
2023-06-01 14:23 ` [PATCH v1 6/6] KVM: x86: Advertise LASS CPUID to user space Zeng Guang
2023-06-02  0:35 ` [PATCH v1 0/6] LASS KVM virtualization support Sean Christopherson
2023-06-06  2:22   ` Zeng Guang
2023-06-05  1:39 ` Binbin Wu
2023-06-06  2:40   ` Zeng Guang
2023-06-27 17:08 ` Sean Christopherson
2023-06-28  8:42   ` Zeng Guang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230601142309.6307-6-guang.zeng@intel.com \
    --to=guang.zeng@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.