Received: by 2002:a05:7412:518d:b0:e2:908c:2ebd with SMTP id fn13csp525967rdb; Thu, 5 Oct 2023 12:57:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGxt5FSFFIU6jdzBzYrKuKFXesELcp+w0mRW49craMS+YlTM0sg+XsxNxzwa7vn3JmhYSV1 X-Received: by 2002:a05:6a21:798a:b0:165:2cee:7aa5 with SMTP id bh10-20020a056a21798a00b001652cee7aa5mr5329107pzc.27.1696535857133; Thu, 05 Oct 2023 12:57:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696535857; cv=none; d=google.com; s=arc-20160816; b=vkG4TW+o3rBvO6YydYAuiHiP+0pD+4/XkMLlG5bxTXUa81p7NjiaBmU5EiLlEn2VBl 9nEzuV/oDEwyVuSVaCRbU4XRylZjXcRdPYWHz0aCyXRUm4RgEhm+eDuwHumkhGWM7nXJ 4D+/TNfrM97nrMRZVNN6UqFluZE4xnNXWOdt4ab43Q/cOIa0j2XgnkyqShyykACkrBll sbpbFTp/epX/0H4OQ6bt43pXja1Yhr2qlM0CUHQEHwPeBCfV5mBZ9eMx4dikBo5Wlt7k iXoStNc1U4O4QD3d7M8nkPh94otgm8v9iXXZIB8KGiCh7cpFtHdS6vqXV8v/77/OUYEO Xv4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=YQWbXPKjZTXVwmXtVpuoErTcrfALoqs6eyiUJub6MzA=; fh=dyN8rlR8DIsO7hGArNuYLUXtXvDlE6dkZecyfb1jp0w=; b=cel5s7ZuY5VbciftLf5QFqvv7gWyI0/h2KWwOP5l+qY8dAIDH7+50SKPcgXCDxNULj 9d5RTkaAB8BX8h0MyZ7EiStlSB/MK4dbjtKuJZfLoZo95Bhh8GdwfO5crv5dAUQf3kJo Qigz9/yv8T319j0SG17yJWEmVOj8/k0BRvtz5ulppPOqr4BLioS5V4rWY4xAeyHMy/D3 hGqL/YrJdwyxV4ZxXykfiESvkL3C1OQJsaWZkzbNQeosilqjnomNATFDJqwmqtFygFRk qHYlAQLwWwAq+4yFLxjNLkNwt0UOJWj8HE3/IhlphKMFJej9WtKNoXtVb+5hehgvVg6Z Vm/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Fplqqoct; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id h5-20020a056a00170500b00690d00d52efsi2170134pfc.264.2023.10.05.12.57.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 12:57:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Fplqqoct; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 6593C836F40E; Thu, 5 Oct 2023 12:57:30 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232011AbjJET4F (ORCPT + 99 others); Thu, 5 Oct 2023 15:56:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231576AbjJETzs (ORCPT ); Thu, 5 Oct 2023 15:55:48 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 835CFDE; Thu, 5 Oct 2023 12:55:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1696535747; x=1728071747; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GiJpifxZQPr3x5nJ9GwyBlCzwdV0vc7uO6aAQUWW42c=; b=FplqqoctjFPDXOq2zs0ndFn/GYn0GW3epwe1lXSQ3kVfaFDgyrmPz59R upgfG+IzRiBwCW08Y7zEkEeROpzh+BHYciT0llS3Ws7t5HYgp/RXu6uLX gngUyZves0mGxVh/HLXgL/0yrW0qnwNsehKKIJ6uJW9lq1TYdcvGLZDee aSrPClC060gANspFz2Abx0CUponz2zUpSDnlCeh9+83spnkD1C86bBrBe KRgtMilpwgVMvna5dK/zxOqMVPenQCCj97UbbQJqbubRjlT3Lu4Oq4AFX f4AOQkO1OgZCa9s0calb2tURcVU1ObB3LdDwcb6Z9K1kH0yNzj4OeR3Ki A==; X-IronPort-AV: E=McAfee;i="6600,9927,10854"; a="386432569" X-IronPort-AV: E=Sophos;i="6.03,203,1694761200"; d="scan'208";a="386432569" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Oct 2023 12:55:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10854"; a="755600121" X-IronPort-AV: E=Sophos;i="6.03,203,1694761200"; d="scan'208";a="755600121" Received: from jithujos.sc.intel.com ([172.25.103.66]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Oct 2023 12:55:44 -0700 From: Jithu Joseph To: ilpo.jarvinen@linux.intel.com, hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, rostedt@goodmis.org, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com, pengfei.xu@intel.com Subject: [PATCH v4 3/9] platform/x86/intel/ifs: Gen2 scan image loading Date: Thu, 5 Oct 2023 12:51:31 -0700 Message-Id: <20231005195137.3117166-4-jithu.joseph@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231005195137.3117166-1-jithu.joseph@intel.com> References: <20230929202436.2850388-1-jithu.joseph@intel.com> <20231005195137.3117166-1-jithu.joseph@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on snail.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 05 Oct 2023 12:57:30 -0700 (PDT) Scan image loading flow for newer IFS generations are slightly different from that of current generation. In newer schemes, loading need not be done once for each socket as was done in gen0. Also the width of NUM_CHUNKS bitfield in SCAN_HASHES_STATUS MSR has increased from 8 -> 16 bits. Similarly there are width differences for CHUNK_AUTHENTICATION_STATUS too. Further the parameter to AUTHENTICATE_AND_COPY_CHUNK is passed differently in newer generations. Signed-off-by: Jithu Joseph Reviewed-by: Tony Luck Reviewed-by: Ilpo Järvinen Tested-by: Pengfei Xu --- drivers/platform/x86/intel/ifs/ifs.h | 27 +++++++ drivers/platform/x86/intel/ifs/load.c | 112 +++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h index d666aeed20fc..4824316b3acd 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -137,6 +137,8 @@ #define MSR_CHUNKS_AUTHENTICATION_STATUS 0x000002c5 #define MSR_ACTIVATE_SCAN 0x000002c6 #define MSR_SCAN_STATUS 0x000002c7 +#define MSR_SAF_CTRL 0x000004f0 + #define SCAN_NOT_TESTED 0 #define SCAN_TEST_PASS 1 #define SCAN_TEST_FAIL 2 @@ -158,6 +160,19 @@ union ifs_scan_hashes_status { }; }; +union ifs_scan_hashes_status_gen2 { + u64 data; + struct { + u16 chunk_size; + u16 num_chunks; + u32 error_code :8; + u32 chunks_in_stride :9; + u32 rsvd :2; + u32 max_core_limit :12; + u32 valid :1; + }; +}; + /* MSR_CHUNKS_AUTH_STATUS bit fields */ union ifs_chunks_auth_status { u64 data; @@ -170,6 +185,16 @@ union ifs_chunks_auth_status { }; }; +union ifs_chunks_auth_status_gen2 { + u64 data; + struct { + u16 valid_chunks; + u16 total_chunks; + u32 error_code :8; + u32 rsvd2 :24; + }; +}; + /* MSR_ACTIVATE_SCAN bit fields */ union ifs_scan { u64 data; @@ -230,6 +255,7 @@ struct ifs_test_caps { * @scan_details: opaque scan status code from h/w * @cur_batch: number indicating the currently loaded test file * @generation: IFS test generation enumerated by hardware + * @chunk_size: size of a test chunk */ struct ifs_data { int loaded_version; @@ -240,6 +266,7 @@ struct ifs_data { u64 scan_details; u32 cur_batch; u32 generation; + u32 chunk_size; }; struct ifs_work { diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c index 851c97cc6a6b..6b827247945b 100644 --- a/drivers/platform/x86/intel/ifs/load.c +++ b/drivers/platform/x86/intel/ifs/load.c @@ -2,6 +2,7 @@ /* Copyright(c) 2022 Intel Corporation. */ #include +#include #include #include @@ -26,6 +27,11 @@ union meta_data { #define IFS_HEADER_SIZE (sizeof(struct microcode_header_intel)) #define META_TYPE_IFS 1 +#define INVALIDATE_STRIDE 0x1UL +#define IFS_GEN_STRIDE_AWARE 2 +#define AUTH_INTERRUPTED_ERROR 5 +#define IFS_AUTH_RETRY_CT 10 + static struct microcode_header_intel *ifs_header_ptr; /* pointer to the ifs image header */ static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */ static u64 ifs_test_image_ptr; /* 256B aligned address of test pattern */ @@ -44,7 +50,10 @@ static const char * const scan_hash_status[] = { static const char * const scan_authentication_status[] = { [0] = "No error reported", [1] = "Attempt to authenticate a chunk which is already marked as authentic", - [2] = "Chunk authentication error. The hash of chunk did not match expected value" + [2] = "Chunk authentication error. The hash of chunk did not match expected value", + [3] = "Reserved", + [4] = "Chunk outside the current stride", + [5] = "Authentication flow interrupted", }; #define MC_HEADER_META_TYPE_END (0) @@ -154,6 +163,102 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work) complete(&ifs_done); } +static int get_num_chunks(int gen, union ifs_scan_hashes_status_gen2 status) +{ + return gen >= IFS_GEN_STRIDE_AWARE ? status.chunks_in_stride : status.num_chunks; +} + +static bool need_copy_scan_hashes(struct ifs_data *ifsd) +{ + return !ifsd->loaded || + ifsd->generation < IFS_GEN_STRIDE_AWARE || + ifsd->loaded_version != ifs_header_ptr->rev; +} + +static int copy_hashes_authenticate_chunks_gen2(struct device *dev) +{ + union ifs_scan_hashes_status_gen2 hashes_status; + union ifs_chunks_auth_status_gen2 chunk_status; + u32 err_code, valid_chunks, total_chunks; + int i, num_chunks, chunk_size; + union meta_data *ifs_meta; + int starting_chunk_nr; + struct ifs_data *ifsd; + u64 linear_addr, base; + u64 chunk_table[2]; + int retry_count; + + ifsd = ifs_get_data(dev); + + if (need_copy_scan_hashes(ifsd)) { + wrmsrl(MSR_COPY_SCAN_HASHES, ifs_hash_ptr); + rdmsrl(MSR_SCAN_HASHES_STATUS, hashes_status.data); + + /* enumerate the scan image information */ + chunk_size = hashes_status.chunk_size * SZ_1K; + err_code = hashes_status.error_code; + + num_chunks = get_num_chunks(ifsd->generation, hashes_status); + + if (!hashes_status.valid) { + hashcopy_err_message(dev, err_code); + return -EIO; + } + ifsd->loaded_version = ifs_header_ptr->rev; + ifsd->chunk_size = chunk_size; + } else { + num_chunks = ifsd->valid_chunks; + chunk_size = ifsd->chunk_size; + } + + if (ifsd->generation >= IFS_GEN_STRIDE_AWARE) { + wrmsrl(MSR_SAF_CTRL, INVALIDATE_STRIDE); + rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data); + if (chunk_status.valid_chunks != 0) { + dev_err(dev, "Couldn't invalidate installed stride - %d\n", + chunk_status.valid_chunks); + return -EIO; + } + } + + base = ifs_test_image_ptr; + ifs_meta = (union meta_data *)find_meta_data(ifs_header_ptr, META_TYPE_IFS); + starting_chunk_nr = ifs_meta->starting_chunk; + + /* scan data authentication and copy chunks to secured memory */ + for (i = 0; i < num_chunks; i++) { + retry_count = IFS_AUTH_RETRY_CT; + linear_addr = base + i * chunk_size; + + chunk_table[0] = starting_chunk_nr + i; + chunk_table[1] = linear_addr; + do { + wrmsrl(MSR_AUTHENTICATE_AND_COPY_CHUNK, (u64)chunk_table); + rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data); + err_code = chunk_status.error_code; + } while (err_code == AUTH_INTERRUPTED_ERROR && --retry_count); + + if (err_code) { + ifsd->loading_error = true; + auth_err_message(dev, err_code); + return -EIO; + } + } + + valid_chunks = chunk_status.valid_chunks; + total_chunks = chunk_status.total_chunks; + + if (valid_chunks != total_chunks) { + ifsd->loading_error = true; + dev_err(dev, "Couldn't authenticate all the chunks. Authenticated %d total %d.\n", + valid_chunks, total_chunks); + return -EIO; + } + ifsd->valid_chunks = valid_chunks; + + return 0; +} + static int validate_ifs_metadata(struct device *dev) { struct ifs_data *ifsd = ifs_get_data(dev); @@ -206,7 +311,9 @@ static int scan_chunks_sanity_check(struct device *dev) return ret; ifsd->loading_error = false; - ifsd->loaded_version = ifs_header_ptr->rev; + + if (ifsd->generation > 0) + return copy_hashes_authenticate_chunks_gen2(dev); /* copy the scan hash and authenticate per package */ cpus_read_lock(); @@ -226,6 +333,7 @@ static int scan_chunks_sanity_check(struct device *dev) ifs_pkg_auth[curr_pkg] = 1; } ret = 0; + ifsd->loaded_version = ifs_header_ptr->rev; out: cpus_read_unlock(); -- 2.25.1