Received: by 2002:a05:7412:5112:b0:fa:6e18:a558 with SMTP id fm18csp190584rdb; Mon, 22 Jan 2024 17:05:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IHdbHslI62D7GEQo0oN6ZvWQ7xwQCbbqDIZ7V1THzDvpqjmonx1gJZvy6C2yfPoo/j5apD1 X-Received: by 2002:a05:620a:4628:b0:783:a957:b789 with SMTP id br40-20020a05620a462800b00783a957b789mr496931qkb.21.1705971950144; Mon, 22 Jan 2024 17:05:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1705971950; cv=pass; d=google.com; s=arc-20160816; b=VJpCTS/zYFfBMZrywHEBdW04rL2Oj8amyGEYXYdqCSzMmfHcd2Ay/sWC+GA8IIK/u7 EVkv68PWly1LZFE1grv+GSn5oo8uRAUtu7ICk4gXbqeuH9VVWkjYYKTNI9JYixdQDu4I BudS9yhVjx338OxVDzozwIXblR4DzNYCxq85O9ooVU5XfZPnfiVpxSC6+XVo4pz2W6np kE6mXMBhemERWu9M+I+ARlng3+8ZG9AGnVJ1smv9RfMLwU7EAFZOrK4PDYhckGJkWaGO mPWhENsuPbFGAWxeh6eaMxjCBbOIuAHHAfkZrb5XW51qiNmcgDBVF4lTqyuFwALfeaDq +/OA== 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=4W1ZM7gjhJgeftRZFzasL160dCDQctJnPoB2NLxpx7E=; fh=Itbyk7CEvizIrzGEESCqq3I2tZgG1kc/GkVOa3S7Hsg=; b=Vw4BtDGvQPmjANxAJ7EgfMpRtJh0o+Vddi1NLQ71i7k4n9cWs3BkZhsafUFjE9aIGk MsGaPaUhizgxqmH4VZ03lfXtxjSHZt7r93iy8FeZVSoWwCa2+jlkbDXAjz7r3BFIMEMD TaF2uwX0qTv5fqg2tmI05x7Z4GtLHxG2Jknj6Dji2kBX23kkn5s31elXg1d8zA3DvU3T KkqYbEUwuccWWpjCA/MQAFSyBwwq0XcDwg37kmUoqXsJpcs5XtPnPbhlLo8WHP5f7eoc ydMxcPFKvfDb2VHc2tDHwjqTGsuLatJocgUL8qXQrSJ7yJRwS1PW7e4OyO26uxK1W8HC D5Cg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=OrJK0lf3; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34458-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34458-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id du51-20020a05620a47f300b0078391fc99b9si6462435qkb.677.2024.01.22.17.05.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jan 2024 17:05:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-34458-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=OrJK0lf3; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34458-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34458-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.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 3E56A1C22DD6 for ; Tue, 23 Jan 2024 01:05:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8565D152DF3; Tue, 23 Jan 2024 00:22:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="OrJK0lf3" Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 926FB1509BA; Tue, 23 Jan 2024 00:22:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=134.134.136.65 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705969367; cv=none; b=hUoNrXU/Y7tMJerok3CoZigONc6EihZksiAF9jFf5NgPIfsLxVVl7hj9hMlIPx5iGLJ/MW/MqKBdWLLeJAxvpBTr/H/EcLLQneTcGr0UIe+8oDhF2R1os2GqBBQeg1+NYKRicYpMGJ6A351P3Jo4iUhXNkQ18UXKDlyoJevrjCc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705969367; c=relaxed/simple; bh=RlU8JoF2lJVCiCoA2T+BoaCaWes3i9Y4CE5OV12pJso=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HEJLx9ebiYnA9d0yTx0H7P3ELszlEU8uowwjr8G5b7VFBtp27FE2Lbl7MKCqC0qh/aEll7dBo4nt3m/oWSXBtp55j8mZ1Do7bXMJxgUP25Ba2QGi1VHYaZ9qd9+M9guysVBXcuPxb0WGTOOjvD1EDvgjwBygdGJ6p5oPMAXs1RM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=OrJK0lf3; arc=none smtp.client-ip=134.134.136.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1705969365; x=1737505365; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RlU8JoF2lJVCiCoA2T+BoaCaWes3i9Y4CE5OV12pJso=; b=OrJK0lf3KF0efLzKxIZVAO7Uq1ot3wiHD1Amg/kP6PSz2uilEIbz+l/6 mCNky5m28yc3nxtxUtJ87Qb45Rw19qQmDDSQGx8D7ecMukJoRnLUV2bH/ IIumGZGE/bQv/UQRgloSO0U7792PnFQumCoythTES0ChWPEmZoD74Mx2c ipI6JkReVbPEXZuulGA6ipcTp8QFeekMJYsf63BMFilj6K88YhmLeKooX RqT8QHIub4w5NOO7ukjDmudWtB/HTcgGOTOn0h9SV+kSJgtJ5/oXDDc6H FqUwjv6nfR3jztV/OZbKrfVwe8yyNhJdXrR9Y5SUKH1uApDaxHNoh+8ia g==; X-IronPort-AV: E=McAfee;i="6600,9927,10961"; a="405125699" X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="405125699" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 16:22:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="27825663" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 16:22:40 -0800 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , Kai Huang , chen.bo@intel.com, hang.yuan@intel.com, tina.zhang@intel.com Subject: [PATCH v7 11/13] KVM: TDX: Implement merge pages into a large page Date: Mon, 22 Jan 2024 16:22:26 -0800 Message-Id: <4eac53599fb87c41aee14577b66d0a832e6c836b.1705965958.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: 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: Isaku Yamahata Implement merge_private_stp callback. Signed-off-by: Isaku Yamahata --- v7: - Fix subject, x86/tdp_mmu => TDX - comment: use ulink instead of free for clarity v6: - repeat TDH.MEM.PAGE.PROMOTE() on TDX_INTERRUPTED_RESTARTABLE --- arch/x86/kvm/vmx/tdx.c | 74 ++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/tdx_arch.h | 1 + arch/x86/kvm/vmx/tdx_errno.h | 2 + arch/x86/kvm/vmx/tdx_ops.h | 11 ++++++ 4 files changed, 88 insertions(+) diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 10dbe4a4db7a..f26caa496d1b 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1742,6 +1742,51 @@ static int tdx_sept_split_private_spt(struct kvm *kvm, gfn_t gfn, return 0; } +static int tdx_sept_merge_private_spt(struct kvm *kvm, gfn_t gfn, + enum pg_level level, void *private_spt) +{ + int tdx_level = pg_level_to_tdx_sept_level(level); + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + struct tdx_module_args out; + gpa_t gpa = gfn_to_gpa(gfn) & KVM_HPAGE_MASK(level); + u64 err; + + /* See comment in tdx_sept_set_private_spte() */ + do { + err = tdh_mem_page_promote(kvm_tdx->tdr_pa, gpa, tdx_level, &out); + } while (err == TDX_INTERRUPTED_RESTARTABLE); + if (unlikely(err == TDX_ERROR_SEPT_BUSY)) + return -EAGAIN; + if (unlikely(err == (TDX_EPT_INVALID_PROMOTE_CONDITIONS | + TDX_OPERAND_ID_RCX))) + /* + * Some pages are accepted, some pending. Need to wait for TD + * to accept all pages. Tell it the caller. + */ + return -EAGAIN; + if (KVM_BUG_ON(err, kvm)) { + pr_tdx_error(TDH_MEM_PAGE_PROMOTE, err, &out); + return -EIO; + } + WARN_ON_ONCE(out.rcx != __pa(private_spt)); + + /* + * TDH.MEM.PAGE.PROMOTE unlinks the Secure-EPT page for the lower level. + * Flush cache for reuse. + */ + do { + err = tdh_phymem_page_wbinvd(set_hkid_to_hpa(__pa(private_spt), + to_kvm_tdx(kvm)->hkid)); + } while (unlikely(err == (TDX_OPERAND_BUSY | TDX_OPERAND_ID_RCX))); + if (WARN_ON_ONCE(err)) { + pr_tdx_error(TDH_PHYMEM_PAGE_WBINVD, err, NULL); + return -EIO; + } + + tdx_clear_page(__pa(private_spt), PAGE_SIZE); + return 0; +} + static int tdx_sept_zap_private_spte(struct kvm *kvm, gfn_t gfn, enum pg_level level) { @@ -1816,6 +1861,33 @@ static void tdx_track(struct kvm *kvm) } +static int tdx_sept_unzap_private_spte(struct kvm *kvm, gfn_t gfn, + enum pg_level level) +{ + int tdx_level = pg_level_to_tdx_sept_level(level); + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + gpa_t gpa = gfn_to_gpa(gfn) & KVM_HPAGE_MASK(level); + struct tdx_module_args out; + u64 err; + + do { + err = tdh_mem_range_unblock(kvm_tdx->tdr_pa, gpa, tdx_level, &out); + + /* + * tdh_mem_range_block() is accompanied with tdx_track() via kvm + * remote tlb flush. Wait for the caller of + * tdh_mem_range_block() to complete TDX track. + */ + } while (err == (TDX_TLB_TRACKING_NOT_DONE | TDX_OPERAND_ID_SEPT)); + if (unlikely(err == TDX_ERROR_SEPT_BUSY)) + return -EAGAIN; + if (KVM_BUG_ON(err, kvm)) { + pr_tdx_error(TDH_MEM_RANGE_UNBLOCK, err, &out); + return -EIO; + } + return 0; +} + static int tdx_sept_free_private_spt(struct kvm *kvm, gfn_t gfn, enum pg_level level, void *private_spt) { @@ -3309,9 +3381,11 @@ int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops) x86_ops->link_private_spt = tdx_sept_link_private_spt; x86_ops->free_private_spt = tdx_sept_free_private_spt; x86_ops->split_private_spt = tdx_sept_split_private_spt; + x86_ops->merge_private_spt = tdx_sept_merge_private_spt; x86_ops->set_private_spte = tdx_sept_set_private_spte; x86_ops->remove_private_spte = tdx_sept_remove_private_spte; x86_ops->zap_private_spte = tdx_sept_zap_private_spte; + x86_ops->unzap_private_spte = tdx_sept_unzap_private_spte; return 0; diff --git a/arch/x86/kvm/vmx/tdx_arch.h b/arch/x86/kvm/vmx/tdx_arch.h index e663abaa3aa0..aef6103c6515 100644 --- a/arch/x86/kvm/vmx/tdx_arch.h +++ b/arch/x86/kvm/vmx/tdx_arch.h @@ -29,6 +29,7 @@ #define TDH_MNG_KEY_FREEID 20 #define TDH_MNG_INIT 21 #define TDH_VP_INIT 22 +#define TDH_MEM_PAGE_PROMOTE 23 #define TDH_MEM_SEPT_RD 25 #define TDH_VP_RD 26 #define TDH_MNG_KEY_RECLAIMID 27 diff --git a/arch/x86/kvm/vmx/tdx_errno.h b/arch/x86/kvm/vmx/tdx_errno.h index d08b4d14e57b..4142487f987e 100644 --- a/arch/x86/kvm/vmx/tdx_errno.h +++ b/arch/x86/kvm/vmx/tdx_errno.h @@ -24,6 +24,8 @@ #define TDX_FLUSHVP_NOT_DONE 0x8000082400000000ULL #define TDX_EPT_WALK_FAILED 0xC0000B0000000000ULL #define TDX_EPT_ENTRY_NOT_FREE 0xC0000B0200000000ULL +#define TDX_TLB_TRACKING_NOT_DONE 0xC0000B0800000000ULL +#define TDX_EPT_INVALID_PROMOTE_CONDITIONS 0xC0000B0900000000ULL #define TDX_EPT_ENTRY_STATE_INCORRECT 0xC0000B0D00000000ULL /* diff --git a/arch/x86/kvm/vmx/tdx_ops.h b/arch/x86/kvm/vmx/tdx_ops.h index 772e2e7d61e7..e2b9f1c3d67f 100644 --- a/arch/x86/kvm/vmx/tdx_ops.h +++ b/arch/x86/kvm/vmx/tdx_ops.h @@ -262,6 +262,17 @@ static inline u64 tdh_mem_page_demote(hpa_t tdr, gpa_t gpa, int level, hpa_t pag return tdx_seamcall_sept(TDH_MEM_PAGE_DEMOTE, &in, out); } +static inline u64 tdh_mem_page_promote(hpa_t tdr, gpa_t gpa, int level, + struct tdx_module_args *out) +{ + struct tdx_module_args in = { + .rcx = gpa | level, + .rdx = tdr, + }; + + return tdx_seamcall_sept(TDH_MEM_PAGE_PROMOTE, &in, out); +} + static inline u64 tdh_mr_extend(hpa_t tdr, gpa_t gpa, struct tdx_module_args *out) { -- 2.25.1