Received: by 2002:a05:7208:9594:b0:7e:5202:c8b4 with SMTP id gs20csp1351616rbb; Mon, 26 Feb 2024 06:48:09 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXji8eih0t+nobYL/2I1q3vz7RjoBw6bwWfGyH/83h90pY8TxralrGU2/3zOF7drSCTENa07paPkc3le0ywkvIfiRRiaa/C+BGi+5ySyA== X-Google-Smtp-Source: AGHT+IHtdGuvTM/bMn0HpHf1bFzCVkF/YVEZ/AbN82OFn+uKeExHztuy97WXuZAtxGFi+zixtZjP X-Received: by 2002:ae9:e116:0:b0:787:80bb:c2e7 with SMTP id g22-20020ae9e116000000b0078780bbc2e7mr6649270qkm.51.1708958889076; Mon, 26 Feb 2024 06:48:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708958889; cv=pass; d=google.com; s=arc-20160816; b=N6sBFq4HpNJTwjixjmL1RX9CxU243ugxVDBvxJYUVx2nfpATxw0FpbQX62pbUdbDEN jQZD2ZlojOt4302nFG5mC2WAfhtLALOQyYd54jz8snjfQfHQCIoqywAywVIPJee8N229 9EcTarsvsoN3yiRxzj+6qZbAD5V8+byKzDFAFomPsZr9OrQ2qrtkwioeAnyv8lv9vQId 6kUWWZn7kq3iaXF5CewKkSOdzghkpTBr8eu3/xb7iInLE88YuLJX7URYe0JRLiVeq2qo +MThJOdxn0iMCdBfOkjWcWzpUksPq9KPWL/h8uO+tXE1Dptab9UpeEe1VwCsC0iEuibC q9qA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=UtUkxsopGOuyKL99aD2RpbSsknxN3/UH+bUJznUscCw=; fh=XlwOQCl+hXUu1fEODTFOd4b7hCooifwtBkZae7Hop7c=; b=Wy9qWMMD8X5lY0oZYDFQq2VUHTwRX2HG982i6Odh0QkhRtX+Jyfqm1Y2DlCdyLNM4T Mp1y3qLhb3lrFcHoEef+8R0ISeF2ydYDKChvBtENFPOY7yj8Cl7X0KGn5TIRpAphaCu2 9OqI0/oGXiBHU5nyPkbSDjnLJmsgiFQOMAWaAhQYGSd3OhdyuJCGNKqxGbnkkrio8FxB msJXLqowYIz+VkhKaKkFLGSsN2knuoT6U5mjUhvu358xSdOF2zlGPpTinzO1UAJPD2he EWEHc3iGd8J3PpQFHuYOLKonAY0SdEY96WT2L/zy8GmyQ/9SXER7Mg8TTINtxqygHLkc g/uQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=jVSJjN6R; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-81675-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81675-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id h11-20020a37c44b000000b00787c4d11b8csi4693854qkm.669.2024.02.26.06.48.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Feb 2024 06:48:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-81675-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=jVSJjN6R; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-81675-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81675-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 1D2831C271B9 for ; Mon, 26 Feb 2024 14:47:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 52882136641; Mon, 26 Feb 2024 14:36:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jVSJjN6R" Received: from mail-io1-f47.google.com (mail-io1-f47.google.com [209.85.166.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6499135A4E; Mon, 26 Feb 2024 14:36:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.166.47 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708958175; cv=none; b=HvZxQQ4k+U2L3hlsQZC2E9YAwIzOh9hct6EFs26PuLCer4kvCHBaarLVeJlFLQWqqwScNdhkZMB5q+eW3N5PsynHKwbiEab9B8t1n3RU7/bLJI5eXlGtGjPUDXTAj7uGALlgH0V0zcXGJizXprbFVT/6kxNbY77K/O8p2JIlIvE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708958175; c=relaxed/simple; bh=s8BFiuzUQau5p+yaQ0/fjHGiJ1v48d8tcf7X9leFdDk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IGAnKKbC+wowGBCSQmM81Ju1K8ke+RsPW8twRijgZr4/HaHn6+raKKKtsAzEiJSp/P8Q/3NPXIGSZ+ji+3MRLMBZF6byy4Ck0M2QUJsaCqK1PbdTrTnl2e8VSE3hAc1SVexqxmMd1wfYMVc3FoMab7gNg6OK+J+VsgTMSdv4h2c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jVSJjN6R; arc=none smtp.client-ip=209.85.166.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-io1-f47.google.com with SMTP id ca18e2360f4ac-7c78573f31aso149892139f.3; Mon, 26 Feb 2024 06:36:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1708958172; x=1709562972; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UtUkxsopGOuyKL99aD2RpbSsknxN3/UH+bUJznUscCw=; b=jVSJjN6RAGsTofl+30a2DdIfw9wj3m5ZRsCEJMr7Gaq2/lsNAO1tRkNZRV3LeX9/5d 0A8x9mDQkaZfDPKGBbJmZWoLV1g9csSsyd5gAjHNm82G/ztVPGzf62S2ILd0s38vRXF2 +isNQobyi0UYJcmI5KIR16Qumv+zv7LSBO/Tzxa9XGen6Vzj9mLmmSqQQ5Es0ZKLUFq9 BJ2Bgr7zny56w9Oov0TiHwCKAGy8FMXIFAE141A9YFGBd2e8c54GirqhPFHD+K1flmrW OJpvcFULu8ANJ/z7m6FpX6tInWcAJcCeTFWCs9j3gZ/MqL6qPP0tL5JYLLSsjt+X8JXP 4ftQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708958172; x=1709562972; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UtUkxsopGOuyKL99aD2RpbSsknxN3/UH+bUJznUscCw=; b=SrW+3iOUoMqF4et23l5LqGs6vGW3/8uhK71TfSV3iOa7nrLmnpxB46wus16g8q+0b6 7Sr1LqohqXEjpisF7zXgiygQnNRQ6Vn+n8eJ8cPhqCCNAu61fX4D+3oGaPQWAyhQ9Kd7 ojXYvVgEOfR6pDGuce/b69u9giE5c76xMKurZK13nEEI+41RWRkAJHDn/tRDajCl+r5r 3FBzgwV/sgA7kFmlIpirJIDd35fCrdglJ29WhIH3JyvQpcEhSQlW2DPWBfCgAuDkSu1x YE1pjibJWzR9fJ94aeDC9W2nsrzmd2B1HB4BD6+GsHjdDhTAmZPGsCtPJx3Gl/H3o3Dg 0Q7Q== X-Forwarded-Encrypted: i=1; AJvYcCX6sgo9YpJVvEQM8cLJhYD46VFHyvfBJO2T4EfdXawyyky2ywCGMQzF1HsPyWncbEyvfBviXwUgOWB2KLq/ixKoN/Ng X-Gm-Message-State: AOJu0Yzs1YvZdGtBeYqAG1aY6Nb8sb/bNhOBKTEnUaf3NtOBw90VTSjy P67ckPmqT/0P7OC8m40Q0rvxSTdFOWX8BN0PRSgUYC9o6MrKHIABCcm6ZRgi X-Received: by 2002:a92:d588:0:b0:365:1305:fac5 with SMTP id a8-20020a92d588000000b003651305fac5mr7579709iln.0.1708958172552; Mon, 26 Feb 2024 06:36:12 -0800 (PST) Received: from localhost ([47.88.5.130]) by smtp.gmail.com with ESMTPSA id l64-20020a638843000000b005dccf9e3b74sm4047652pgd.92.2024.02.26.06.36.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2024 06:36:12 -0800 (PST) From: Lai Jiangshan To: linux-kernel@vger.kernel.org Cc: Lai Jiangshan , Hou Wenlong , Linus Torvalds , Peter Zijlstra , Sean Christopherson , Thomas Gleixner , Borislav Petkov , Ingo Molnar , kvm@vger.kernel.org, Paolo Bonzini , x86@kernel.org, Kees Cook , Juergen Gross , Dave Hansen , "H. Peter Anvin" Subject: [RFC PATCH 29/73] KVM: x86/PVM: Implement allowed range checking for #PF Date: Mon, 26 Feb 2024 22:35:46 +0800 Message-Id: <20240226143630.33643-30-jiangshanlai@gmail.com> X-Mailer: git-send-email 2.19.1.6.gb485710b In-Reply-To: <20240226143630.33643-1-jiangshanlai@gmail.com> References: <20240226143630.33643-1-jiangshanlai@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Lai Jiangshan In PVM, guest is only allowed to be running in the reserved virtual address range provided by the hypervisor. So guest needs to get the allowed range information from the MSR and the hypervisor needs to check the fault address and prevent install mapping in the #PF handler. Signed-off-by: Lai Jiangshan Signed-off-by: Hou Wenlong --- arch/x86/kvm/pvm/pvm.c | 74 ++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/pvm/pvm.h | 5 +++ 2 files changed, 79 insertions(+) diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c index 92eef226df28..26b2201f7dde 100644 --- a/arch/x86/kvm/pvm/pvm.c +++ b/arch/x86/kvm/pvm/pvm.c @@ -144,6 +144,28 @@ static void pvm_write_guest_kernel_gs_base(struct vcpu_pvm *pvm, u64 data) pvm->msr_kernel_gs_base = data; } +static __always_inline bool pvm_guest_allowed_va(struct kvm_vcpu *vcpu, u64 va) +{ + struct vcpu_pvm *pvm = to_pvm(vcpu); + + if ((s64)va > 0) + return true; + if (pvm->l4_range_start <= va && va < pvm->l4_range_end) + return true; + if (pvm->l5_range_start <= va && va < pvm->l5_range_end) + return true; + + return false; +} + +static bool pvm_disallowed_va(struct kvm_vcpu *vcpu, u64 va) +{ + if (is_noncanonical_address(va, vcpu)) + return true; + + return !pvm_guest_allowed_va(vcpu, va); +} + // switch_to_smod() and switch_to_umod() switch the mode (smod/umod) and // the CR3. No vTLB flushing when switching the CR3 per PVM Spec. static inline void switch_to_smod(struct kvm_vcpu *vcpu) @@ -380,6 +402,48 @@ static void pvm_sched_in(struct kvm_vcpu *vcpu, int cpu) { } +static void pvm_set_msr_linear_address_range(struct vcpu_pvm *pvm, + u64 pml4_i_s, u64 pml4_i_e, + u64 pml5_i_s, u64 pml5_i_e) +{ + pvm->msr_linear_address_range = ((0xfe00 | pml4_i_s) << 0) | + ((0xfe00 | pml4_i_e) << 16) | + ((0xfe00 | pml5_i_s) << 32) | + ((0xfe00 | pml5_i_e) << 48); + + pvm->l4_range_start = (0x1fffe00 | pml4_i_s) * PT_L4_SIZE; + pvm->l4_range_end = (0x1fffe00 | pml4_i_e) * PT_L4_SIZE; + pvm->l5_range_start = (0xfe00 | pml5_i_s) * PT_L5_SIZE; + pvm->l5_range_end = (0xfe00 | pml5_i_e) * PT_L5_SIZE; +} + +static void pvm_set_default_msr_linear_address_range(struct vcpu_pvm *pvm) +{ + pvm_set_msr_linear_address_range(pvm, pml4_index_start, pml4_index_end, + pml5_index_start, pml5_index_end); +} + +static bool pvm_check_and_set_msr_linear_address_range(struct vcpu_pvm *pvm, u64 msr) +{ + u64 pml4_i_s = (msr >> 0) & 0x1ff; + u64 pml4_i_e = (msr >> 16) & 0x1ff; + u64 pml5_i_s = (msr >> 32) & 0x1ff; + u64 pml5_i_e = (msr >> 48) & 0x1ff; + + /* PVM specification requires those bits to be all set. */ + if ((msr & 0xff00ff00ff00ff00) != 0xff00ff00ff00ff00) + return false; + + /* Guest ranges should be inside what the hypervisor can provide. */ + if (pml4_i_s < pml4_index_start || pml4_i_e > pml4_index_end || + pml5_i_s < pml5_index_start || pml5_i_e > pml5_index_end) + return false; + + pvm_set_msr_linear_address_range(pvm, pml4_i_s, pml4_i_e, pml5_i_s, pml5_i_e); + + return true; +} + static int pvm_get_msr_feature(struct kvm_msr_entry *msr) { return 1; @@ -456,6 +520,9 @@ static int pvm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_PVM_SWITCH_CR3: msr_info->data = pvm->msr_switch_cr3; break; + case MSR_PVM_LINEAR_ADDRESS_RANGE: + msr_info->data = pvm->msr_linear_address_range; + break; default: ret = kvm_get_msr_common(vcpu, msr_info); } @@ -552,6 +619,10 @@ static int pvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_PVM_SWITCH_CR3: pvm->msr_switch_cr3 = msr_info->data; break; + case MSR_PVM_LINEAR_ADDRESS_RANGE: + if (!pvm_check_and_set_msr_linear_address_range(pvm, msr_info->data)) + return 1; + break; default: ret = kvm_set_msr_common(vcpu, msr_info); } @@ -1273,6 +1344,7 @@ static void pvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) pvm->msr_retu_rip_plus2 = 0; pvm->msr_rets_rip_plus2 = 0; pvm->msr_switch_cr3 = 0; + pvm_set_default_msr_linear_address_range(pvm); } static int pvm_vcpu_create(struct kvm_vcpu *vcpu) @@ -1520,6 +1592,8 @@ static struct kvm_x86_ops pvm_x86_ops __initdata = { .msr_filter_changed = pvm_msr_filter_changed, .complete_emulated_msr = kvm_complete_insn_gp, .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector, + + .disallowed_va = pvm_disallowed_va, .vcpu_gpc_refresh = pvm_vcpu_gpc_refresh, }; diff --git a/arch/x86/kvm/pvm/pvm.h b/arch/x86/kvm/pvm/pvm.h index 39506ddbe5c5..bf3a6a1837c0 100644 --- a/arch/x86/kvm/pvm/pvm.h +++ b/arch/x86/kvm/pvm/pvm.h @@ -82,6 +82,11 @@ struct vcpu_pvm { unsigned long msr_switch_cr3; unsigned long msr_linear_address_range; + u64 l4_range_start; + u64 l4_range_end; + u64 l5_range_start; + u64 l5_range_end; + struct kvm_segment segments[NR_VCPU_SREG]; struct desc_ptr idt_ptr; struct desc_ptr gdt_ptr; -- 2.19.1.6.gb485710b