From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1C30C3DA7A for ; Fri, 6 Jan 2023 19:24:57 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2D8458E0002; Fri, 6 Jan 2023 14:24:57 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 261308E0001; Fri, 6 Jan 2023 14:24:57 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 102A28E0002; Fri, 6 Jan 2023 14:24:57 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id EE4308E0001 for ; Fri, 6 Jan 2023 14:24:56 -0500 (EST) Received: from smtpin20.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id C37C5C0EC0 for ; Fri, 6 Jan 2023 19:24:56 +0000 (UTC) X-FDA: 80325351792.20.36A6016 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by imf08.hostedemail.com (Postfix) with ESMTP id 20B96160006 for ; Fri, 6 Jan 2023 19:24:53 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=m+QaUtEn; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf08.hostedemail.com: domain of dave.hansen@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=dave.hansen@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1673033095; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=XYza9BPBlPB0ghrTOGt8QUt95UHM+4R3mJBszAdN9Ao=; b=RGUlNwVQf+gJlHkkUrrQtFTXH7jBOzTvCfPK5EJPvY4Slasxzm0Z5gvu8+vRFNsRZZC9ee p+hHZE3RD8H84wJv1AmVGIbB3WJ58bbPV58/fKMOb59RjGHcajlyvzDSs8LffwS++qR3Hw H+QHlcTxdJ4Uym3wEw7fqupvPWbi4/Y= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=m+QaUtEn; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf08.hostedemail.com: domain of dave.hansen@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=dave.hansen@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1673033095; a=rsa-sha256; cv=none; b=x7TaZg5XPPldb+SssSWPsmEKeKVLoCFqTFx1bQlr3jBzM8s47z6ucuoy1M6NeELAIrbhSu K2bG0mVv+F23aCZ8MX/RPqiiVq69/DNtbeYBlPdZKbQa2LE/XwgRU4yba6ZDhWxbOWdiuj cdImvgQj7xqYw4/LZvncACiUJpq3Zw0= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673033094; x=1704569094; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=urJOmVPJ99y51Km3uk2nWj9LuSQ8wgumbaoe8ilFZxI=; b=m+QaUtEnTsP48Ff7cKEsDqT1zEgrRgUzRVvNix7Su67wZlxDGRCDMXFO uJtbnNvKt6GpngjJnPXnQ2KZ2Y2ufuJ5r/8ShemWZ31JH1MULZKZysDt9 me0TclQcNQOLlBW9X5WiMDkUWe2FiGDyeGZyXurp3Wtc1kjjt3dJJ+hMo AWp073uikHtNxpFc972CHyROZwYY+M9QUz8NsMZBIzyv+ZPeG+nJvCvD1 NG8swMEH/X7Ljed7TPeVHf6ZheV9M/GwKcbZ0ivb78LDitTAiC1Ws/a0x sOLG/zIHAtUODZ6yzeao9lsyizDuKIEogw57rQ4mFngb+Q0xBsrzkYc+c g==; X-IronPort-AV: E=McAfee;i="6500,9779,10582"; a="323789763" X-IronPort-AV: E=Sophos;i="5.96,306,1665471600"; d="scan'208";a="323789763" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2023 11:24:52 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10582"; a="688391354" X-IronPort-AV: E=Sophos;i="5.96,306,1665471600"; d="scan'208";a="688391354" Received: from xiangyuy-mobl.amr.corp.intel.com (HELO [10.212.251.186]) ([10.212.251.186]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2023 11:24:51 -0800 Message-ID: Date: Fri, 6 Jan 2023 11:24:51 -0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Subject: Re: [PATCH v8 08/16] x86/virt/tdx: Add placeholder to construct TDMRs to cover all TDX memory regions Content-Language: en-US To: Kai Huang , linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: linux-mm@kvack.org, peterz@infradead.org, tglx@linutronix.de, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com, rafael.j.wysocki@intel.com, kirill.shutemov@linux.intel.com, ying.huang@intel.com, reinette.chatre@intel.com, len.brown@intel.com, tony.luck@intel.com, ak@linux.intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com, bagasdotme@gmail.com, sagis@google.com, imammedo@redhat.com References: From: Dave Hansen In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Rspam-User: X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: 20B96160006 X-Stat-Signature: k5txgq8te3myirsaru9to3nrzonmc7br X-HE-Tag: 1673033093-347841 X-HE-Meta: U2FsdGVkX1+xhL8T3h1G/yhzo1KG8JJjl6GngTvj5+dYubM7e4XplyIY7qia4QLpcMzdV8KqtCJqiCOx0EnxwlJpILlCMBL8iPIs91xTXMCMdzis/q7/vtBLCxj3dejuwfNA/GN5ai0jThDNdsfRg7UjPzGeQNQbQHTC+IC2WJx1RpuVc+IEfT6Y3uWlrrAwZ7p+SqmCj2j6ktFxm3XpJ/hnmKHdB0Gym3qubwky+Afv7gVlZ3u6FTyfT7WfdaAY2A1NNeb2ttzAsg7Bv1TiwCDOQ54x0mOWDZn1Mr9Li61aULszOXDw/5VEPxWvTa1Xbye9arcdiy+KNnBHrJInh1kuLwdaDMsy1iS4wJGNcNfXadZgCMEcWvjfphOr27DBKsCwcDl9bXG6Vtv9To+/50ELNhUXQAVLOA+KtCW2eR7bDLoRJo1k06po71fgjBwm2uOCp1aovq4XGr+bBkQPsNYJo8Yluc6BoJLsCHvVLhBDXjmyo4i0WFoyQX8Q/9ReL5jn2ry7DkH0fpar1ugLBZwcaud+GEiFm057G63ufyXCsgfTi7P3BiFZMLiRRSv683X29rn/PA0aOdWYXt10Q5sq/J/ZQ7AxGkfJBJDoLov2nnQw59puB8YH2KnLqytVJS6AZk6JHHxPCOc2ec60/CS7L80QCRG7xZ/mhyCmI957/TDHvVL6gGfKn6YPdR/x/CduiPqlQg4oINnsyfxdzR6XeHxR9a1TmJPrbz27vHgepZtH8M57FSevfMfVSuRnnjBQu4igD/b3sqPC5AGGu8XaQwWNalHePESYCWYeve6AEHK/CjaRYvBumO+B/jboKw9EVUk08Mu8i+WGkBfeczLfslTsq5p6ybvUfLwOQVE= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: > +struct tdmr_info_list { > + struct tdmr_info *first_tdmr; This is named badly. This is really a pointer to an array. While it _does_ of course point to the first member of the array, the naming should make it clear that there are multiple tdmr_infos here. > + int tdmr_sz; > + int max_tdmrs; > + int nr_tdmrs; /* Actual number of TDMRs */ > +}; This 'tdmr_info_list's is declared in an unfortunate place. I thought the tdmr_size_single() function below was related to it. Also, tdmr_sz and max_tdmrs can both be derived from 'sysinfo'. Do they really need to be stored here? If so, I think I'd probably do something like this with the structure: struct tdmr_info_list { struct tdmr_info *tdmrs; int nr_consumed_tdmrs; // How many @tdmrs are in use /* Metadata for freeing this structure: */ int tdmr_sz; // Size of one 'tdmr_info' (has a flex array) int max_tdmrs; // How many @tdmrs are allocated }; Modulo whataver folks are doing for comments these days. > +/* Calculate the actual TDMR size */ > +static int tdmr_size_single(u16 max_reserved_per_tdmr) > +{ > + int tdmr_sz; > + > + /* > + * The actual size of TDMR depends on the maximum > + * number of reserved areas. > + */ > + tdmr_sz = sizeof(struct tdmr_info); > + tdmr_sz += sizeof(struct tdmr_reserved_area) * max_reserved_per_tdmr; > + > + return ALIGN(tdmr_sz, TDMR_INFO_ALIGNMENT); > +} > + > +static int alloc_tdmr_list(struct tdmr_info_list *tdmr_list, > + struct tdsysinfo_struct *sysinfo) > +{ > + size_t tdmr_sz, tdmr_array_sz; > + void *tdmr_array; > + > + tdmr_sz = tdmr_size_single(sysinfo->max_reserved_per_tdmr); > + tdmr_array_sz = tdmr_sz * sysinfo->max_tdmrs; > + > + /* > + * To keep things simple, allocate all TDMRs together. > + * The buffer needs to be physically contiguous to make > + * sure each TDMR is physically contiguous. > + */ > + tdmr_array = alloc_pages_exact(tdmr_array_sz, > + GFP_KERNEL | __GFP_ZERO); > + if (!tdmr_array) > + return -ENOMEM; > + > + tdmr_list->first_tdmr = tdmr_array; > + /* ^ probably missing whitepsace before the comment > + * Keep the size of TDMR to find the target TDMR > + * at a given index in the TDMR list. > + */ > + tdmr_list->tdmr_sz = tdmr_sz; > + tdmr_list->max_tdmrs = sysinfo->max_tdmrs; > + tdmr_list->nr_tdmrs = 0; > + > + return 0; > +} > + > +static void free_tdmr_list(struct tdmr_info_list *tdmr_list) > +{ > + free_pages_exact(tdmr_list->first_tdmr, > + tdmr_list->max_tdmrs * tdmr_list->tdmr_sz); > +} > + > +/* > + * Construct a list of TDMRs on the preallocated space in @tdmr_list > + * to cover all TDX memory regions in @tmb_list based on the TDX module > + * information in @sysinfo. > + */ > +static int construct_tdmrs(struct list_head *tmb_list, > + struct tdmr_info_list *tdmr_list, > + struct tdsysinfo_struct *sysinfo) > +{ > + /* > + * TODO: > + * > + * - Fill out TDMRs to cover all TDX memory regions. > + * - Allocate and set up PAMTs for each TDMR. > + * - Designate reserved areas for each TDMR. > + * > + * Return -EINVAL until constructing TDMRs is done > + */ > + return -EINVAL; > +} > + > static int init_tdx_module(void) > { > /* > @@ -358,6 +439,7 @@ static int init_tdx_module(void) > TDSYSINFO_STRUCT_SIZE, TDSYSINFO_STRUCT_ALIGNMENT); > struct cmr_info cmr_array[MAX_CMRS] __aligned(CMR_INFO_ARRAY_ALIGNMENT); > struct tdsysinfo_struct *sysinfo = &PADDED_STRUCT(tdsysinfo); > + struct tdmr_info_list tdmr_list; > int ret; > > ret = tdx_get_sysinfo(sysinfo, cmr_array); > @@ -380,11 +462,19 @@ static int init_tdx_module(void) > if (ret) > goto out; > > + /* Allocate enough space for constructing TDMRs */ > + ret = alloc_tdmr_list(&tdmr_list, sysinfo); > + if (ret) > + goto out_free_tdx_mem; > + > + /* Cover all TDX-usable memory regions in TDMRs */ > + ret = construct_tdmrs(&tdx_memlist, &tdmr_list, sysinfo); > + if (ret) > + goto out_free_tdmrs; > + > /* > * TODO: > * > - * - Construct a list of TDMRs to cover all TDX-usable memory > - * regions. > * - Pick up one TDX private KeyID as the global KeyID. > * - Configure the TDMRs and the global KeyID to the TDX module. > * - Configure the global KeyID on all packages. > @@ -393,6 +483,16 @@ static int init_tdx_module(void) > * Return error before all steps are done. > */ > ret = -EINVAL; > +out_free_tdmrs: > + /* > + * Free the space for the TDMRs no matter the initialization is > + * successful or not. They are not needed anymore after the > + * module initialization. > + */ > + free_tdmr_list(&tdmr_list); > +out_free_tdx_mem: > + if (ret) > + free_tdx_memlist(&tdx_memlist); > out: > /* > * @tdx_memlist is written here and read at memory hotplug time. > diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h > index 6d32f62e4182..d0c762f1a94c 100644 > --- a/arch/x86/virt/vmx/tdx/tdx.h > +++ b/arch/x86/virt/vmx/tdx/tdx.h > @@ -90,6 +90,29 @@ struct tdsysinfo_struct { > DECLARE_FLEX_ARRAY(struct cpuid_config, cpuid_configs); > } __packed; > > +struct tdmr_reserved_area { > + u64 offset; > + u64 size; > +} __packed; > + > +#define TDMR_INFO_ALIGNMENT 512 > + > +struct tdmr_info { > + u64 base; > + u64 size; > + u64 pamt_1g_base; > + u64 pamt_1g_size; > + u64 pamt_2m_base; > + u64 pamt_2m_size; > + u64 pamt_4k_base; > + u64 pamt_4k_size; > + /* > + * Actual number of reserved areas depends on > + * 'struct tdsysinfo_struct'::max_reserved_per_tdmr. > + */ > + DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); > +} __packed __aligned(TDMR_INFO_ALIGNMENT); > + > /* > * Do not put any hardware-defined TDX structure representations below > * this comment!