Received: by 2002:ab2:69cc:0:b0:1f4:be93:e15a with SMTP id n12csp1819054lqp; Mon, 15 Apr 2024 20:22:07 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCV7scww7HINBhGm40CntxEJcPOWppdb836iUvBCflAnLg1ohoikRBfOqmKxz8AYDqYW4tz5HWOy2KmGJv/CyZcU+tZU1UcUw3jkdyRRpg== X-Google-Smtp-Source: AGHT+IGCm10pKIJFJpHTl+/Msg7ByEsEuqZfwLcH1yrj2RAnfqD3E2WJ4WlobWG6fnloYQUp5/3A X-Received: by 2002:ac2:46e6:0:b0:518:c2fb:a365 with SMTP id q6-20020ac246e6000000b00518c2fba365mr4727585lfo.31.1713237727678; Mon, 15 Apr 2024 20:22:07 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713237727; cv=pass; d=google.com; s=arc-20160816; b=rFOykn60irbV6+nX94xwSlrK1IcXi+WeyrjjOnHafTX40q7URoGGsadh9Q04Wvr0gq yXN5ZCTpT5HpF+T184QXlYvu5vYe41A7HhSZTn/LHepmEqgYPJYFtWkHIPvVUjYGg8Td toJO1eT/nOOWoPuHYeUfpbJqozHk3gGOExcPYPUavUND/YjpifjqItE0hrE4AjoPLLJ3 FhdDGJR38QAR8I/4tH0SqDQk6R0/lHlXXyknTbUbarH0LzHlgoM6ohqZIVPbJfgqdvuR zN2AFRjEyVHZFCeRCe13q9Ab0o8Rfpz3Yaojz6TpYPDbfFQjEhJt9aM+l7MavNWS4mzG Xt5g== 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=wqNqhqD8Cc60+UJD8cMuBCbsavCGZk4UxcBpE0NpZsc=; fh=G1r0sJ0F/0v82zumykPUwC7a5Du5vVkWNEWao5ifD3o=; b=NG0fy+JWL7a6wLnRUgD3gy52aSDju3/ErstNS9noIlztp1h7GzK5a3dPNMM2FMDUMF A53OVY6JbFOMK0Ws1Usw3XVK+Zor2wN7KagEVvKUznYtCtGlooFN4iRgoq35ex54HToD jsqoXTor7V0cPyje4NlIABLw4V9pmXQmcn+DVraywDAqH87YUAX6lSl6mH9MB7fn5rhB fPSsFw9r9sP2fHFhjt4TLwH0sC+gzTkmUSyWeutVDzOx8pXDTyFX3Mi7adehujhceIsU R/FoH/n+2+DLV+wVk+q4m7A4pC2U1sp0cvaB43vkkb3gBOp11apX87tZKgFcwfeIvcAF VaCQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=BLzXyZrL; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-146162-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-146162-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id jg26-20020a170907971a00b00a51c35a6d49si5444159ejc.120.2024.04.15.20.22.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Apr 2024 20:22:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-146162-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=BLzXyZrL; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-146162-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-146162-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 3B0721F22A7B for ; Tue, 16 Apr 2024 03:22:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0E76E42AB9; Tue, 16 Apr 2024 03:20:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BLzXyZrL" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (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 A615421101; Tue, 16 Apr 2024 03:20:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713237618; cv=none; b=n33jipZ8+Ve+p7i6xx1UmSPyc8doCZPUYQfkiKxVepza/g2srhWD8tnzldPVNAc8rD146ZV9L/kg8S8l8P6mrmOSM3SkQ5dxzKXB4TF3E0D+TfZKIxmLqGnK5PSy1WYIigqjrp1SJpjGsL4y+IrAo0n7jzgPjHWJTysbdflDQcI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713237618; c=relaxed/simple; bh=89bT15e6CevT5xo2s/Bq4bDsjzWctn1C7UhVBmT5BG4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WWLuHDy9qlKwk+TQ+3XT8ndmCa4U/UR3vC2ko/VUzAD7a5e5mm2DdPiq3IVdDVXwhK6Rzz+3eY+cs6XgPF+WMa9TnScg1WP60nsiEeohW9SK10sqsaAYgVCqTpkTuDfkyq3NLYADrvJTp1RIcWuvOsakRnVzM1ot8tvq9Fjj+ko= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BLzXyZrL; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1713237617; x=1744773617; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=89bT15e6CevT5xo2s/Bq4bDsjzWctn1C7UhVBmT5BG4=; b=BLzXyZrLWmgs9RKinJjcpIb9FFDbyPCefQ569ux/MME3QhYOy8h9uqfx xGFMS6YsNz6u7srQJiTnyGgl8N8IOaLN//80X7pzeMavrrZNfE2mh15Ql xZfQ2g3M6SXIB+3qZ+YFC0pbuEwwc45U/cgpvloUJfX8hX4zLpuuaLuN0 rrgqXGqRFF+J1eUwhQpnc0WJaSF9FPUu+vcRj8PhN7lyo8bGYwq4A6I6e aFnpaxSQhBvTBjybZB1BHyZnbWipVWbwV7OSPirzfa+eHKg6PJvA1LB8K 4VKf3gJcgcGfRoMCIk+aIaJEbkSeRfRvXwBgeYtyOcU4wg5bKeia6sga/ A==; X-CSE-ConnectionGUID: C8ei2pRTROy6/nzNfTJSbg== X-CSE-MsgGUID: YhjLcSWrTV2rm7MGL2ajTg== X-IronPort-AV: E=McAfee;i="6600,9927,11045"; a="34043356" X-IronPort-AV: E=Sophos;i="6.07,204,1708416000"; d="scan'208";a="34043356" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2024 20:20:15 -0700 X-CSE-ConnectionGUID: sZNQw98gRUa95Y39+ILYNQ== X-CSE-MsgGUID: S9Oy4RZvSaWzpo05Kro9zw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,204,1708416000"; d="scan'208";a="22193604" Received: from b4969161e530.jf.intel.com ([10.165.56.46]) by fmviesa008.fm.intel.com with ESMTP; 15 Apr 2024 20:20:14 -0700 From: Haitao Huang To: jarkko@kernel.org, dave.hansen@linux.intel.com, kai.huang@intel.com, tj@kernel.org, mkoutny@suse.com, linux-kernel@vger.kernel.org, linux-sgx@vger.kernel.org, x86@kernel.org, cgroups@vger.kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, hpa@zytor.com, sohil.mehta@intel.com, tim.c.chen@linux.intel.com Cc: zhiquan1.li@intel.com, kristen@linux.intel.com, seanjc@google.com, zhanb@microsoft.com, anakrish@microsoft.com, mikko.ylinen@linux.intel.com, yangjie@microsoft.com, chrisyan@microsoft.com Subject: [PATCH v12 05/14] x86/sgx: Implement basic EPC misc cgroup functionality Date: Mon, 15 Apr 2024 20:20:02 -0700 Message-Id: <20240416032011.58578-6-haitao.huang@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240416032011.58578-1-haitao.huang@linux.intel.com> References: <20240416032011.58578-1-haitao.huang@linux.intel.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: Kristen Carlson Accardi SGX Enclave Page Cache (EPC) memory allocations are separate from normal RAM allocations, and are managed solely by the SGX subsystem. The existing cgroup memory controller cannot be used to limit or account for SGX EPC memory, which is a desirable feature in some environments. For instance, within a Kubernetes environment, while a user may specify a particular EPC quota for a pod, the orchestrator requires a mechanism to enforce that the pod's actual runtime EPC usage does not exceed the allocated quota. Utilize the misc controller [admin-guide/cgroup-v2.rst, 5-9. Misc] to limit and track EPC allocations per cgroup. Earlier patches have added the "sgx_epc" resource type in the misc cgroup subsystem. Add basic support in SGX driver as the "sgx_epc" resource provider: - Set "capacity" of EPC by calling misc_cg_set_capacity() - Update EPC usage counter, "current", by calling charge and uncharge APIs for EPC allocation and deallocation, respectively. - Setup sgx_epc resource type specific callbacks, which perform initialization and cleanup during cgroup allocation and deallocation, respectively. With these changes, the misc cgroup controller enables users to set a hard limit for EPC usage in the "misc.max" interface file. It reports current usage in "misc.current", the total EPC memory available in "misc.capacity", and the number of times EPC usage reached the max limit in "misc.events". For now, the EPC cgroup simply blocks additional EPC allocation in sgx_alloc_epc_page() when the limit is reached. Reclaimable pages are still tracked in the global active list, only reclaimed by the global reclaimer when the total free page count is lower than a threshold. Later patches will reorganize the tracking and reclamation code in the global reclaimer and implement per-cgroup tracking and reclaiming. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Signed-off-by: Kristen Carlson Accardi Co-developed-by: Haitao Huang Signed-off-by: Haitao Huang Reviewed-by: Jarkko Sakkinen Reviewed-by: Tejun Heo Tested-by: Jarkko Sakkinen --- V12: - Remove CONFIG_CGROUP_SGX_EPC and make sgx cgroup implementation conditionally compiled with CONFIG_CGROUP_MISC. (Jarkko) V11: - Update copyright and format better (Kai) - Create wrappers to remove #ifdefs in c file. (Kai) - Remove unneeded comments (Kai) V10: - Shorten function, variable, struct names, s/sgx_epc_cgroup/sgx_cgroup. (Jarkko) - Use enums instead of booleans for the parameters. (Dave, Jarkko) V8: - Remove null checks for epc_cg in try_charge()/uncharge(). (Jarkko) - Remove extra space, '_INTEL'. (Jarkko) V7: - Use a static for root cgroup (Kai) - Wrap epc_cg field in sgx_epc_page struct with #ifdef (Kai) - Correct check for charge API return (Kai) - Start initialization in SGX device driver init (Kai) - Remove unneeded BUG_ON (Kai) - Split sgx_get_current_epc_cg() out of sgx_epc_cg_try_charge() (Kai) V6: - Split the original large patch"Limit process EPC usage with misc cgroup controller" and restructure it (Kai) --- arch/x86/kernel/cpu/sgx/Makefile | 1 + arch/x86/kernel/cpu/sgx/epc_cgroup.c | 72 ++++++++++++++++++++++++++++ arch/x86/kernel/cpu/sgx/epc_cgroup.h | 72 ++++++++++++++++++++++++++++ arch/x86/kernel/cpu/sgx/main.c | 43 ++++++++++++++++- arch/x86/kernel/cpu/sgx/sgx.h | 21 ++++++++ include/linux/misc_cgroup.h | 2 + 6 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 arch/x86/kernel/cpu/sgx/epc_cgroup.c create mode 100644 arch/x86/kernel/cpu/sgx/epc_cgroup.h diff --git a/arch/x86/kernel/cpu/sgx/Makefile b/arch/x86/kernel/cpu/sgx/Makefile index 9c1656779b2a..400baa7cfb69 100644 --- a/arch/x86/kernel/cpu/sgx/Makefile +++ b/arch/x86/kernel/cpu/sgx/Makefile @@ -1,6 +1,7 @@ obj-y += \ driver.o \ encl.o \ + epc_cgroup.o \ ioctl.o \ main.o obj-$(CONFIG_X86_SGX_KVM) += virt.o diff --git a/arch/x86/kernel/cpu/sgx/epc_cgroup.c b/arch/x86/kernel/cpu/sgx/epc_cgroup.c new file mode 100644 index 000000000000..ff4d4a25dbe7 --- /dev/null +++ b/arch/x86/kernel/cpu/sgx/epc_cgroup.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2022-2024 Intel Corporation. */ + +#include +#include +#include "epc_cgroup.h" + +/* The root SGX EPC cgroup */ +static struct sgx_cgroup sgx_cg_root; + +/** + * sgx_cgroup_try_charge() - try to charge cgroup for a single EPC page + * + * @sgx_cg: The EPC cgroup to be charged for the page. + * Return: + * * %0 - If successfully charged. + * * -errno - for failures. + */ +int sgx_cgroup_try_charge(struct sgx_cgroup *sgx_cg) +{ + return misc_cg_try_charge(MISC_CG_RES_SGX_EPC, sgx_cg->cg, PAGE_SIZE); +} + +/** + * sgx_cgroup_uncharge() - uncharge a cgroup for an EPC page + * @sgx_cg: The charged sgx cgroup. + */ +void sgx_cgroup_uncharge(struct sgx_cgroup *sgx_cg) +{ + misc_cg_uncharge(MISC_CG_RES_SGX_EPC, sgx_cg->cg, PAGE_SIZE); +} + +static void sgx_cgroup_free(struct misc_cg *cg) +{ + struct sgx_cgroup *sgx_cg; + + sgx_cg = sgx_cgroup_from_misc_cg(cg); + if (!sgx_cg) + return; + + kfree(sgx_cg); +} + +static void sgx_cgroup_misc_init(struct misc_cg *cg, struct sgx_cgroup *sgx_cg) +{ + cg->res[MISC_CG_RES_SGX_EPC].priv = sgx_cg; + sgx_cg->cg = cg; +} + +static int sgx_cgroup_alloc(struct misc_cg *cg) +{ + struct sgx_cgroup *sgx_cg; + + sgx_cg = kzalloc(sizeof(*sgx_cg), GFP_KERNEL); + if (!sgx_cg) + return -ENOMEM; + + sgx_cgroup_misc_init(cg, sgx_cg); + + return 0; +} + +const struct misc_res_ops sgx_cgroup_ops = { + .alloc = sgx_cgroup_alloc, + .free = sgx_cgroup_free, +}; + +void sgx_cgroup_init(void) +{ + misc_cg_set_ops(MISC_CG_RES_SGX_EPC, &sgx_cgroup_ops); + sgx_cgroup_misc_init(misc_cg_root(), &sgx_cg_root); +} diff --git a/arch/x86/kernel/cpu/sgx/epc_cgroup.h b/arch/x86/kernel/cpu/sgx/epc_cgroup.h new file mode 100644 index 000000000000..bd9606479e67 --- /dev/null +++ b/arch/x86/kernel/cpu/sgx/epc_cgroup.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _SGX_EPC_CGROUP_H_ +#define _SGX_EPC_CGROUP_H_ + +#include +#include +#include + +#include "sgx.h" + +#ifndef CONFIG_CGROUP_MISC + +#define MISC_CG_RES_SGX_EPC MISC_CG_RES_TYPES +struct sgx_cgroup; + +static inline struct sgx_cgroup *sgx_get_current_cg(void) +{ + return NULL; +} + +static inline void sgx_put_cg(struct sgx_cgroup *sgx_cg) { } + +static inline int sgx_cgroup_try_charge(struct sgx_cgroup *sgx_cg) +{ + return 0; +} + +static inline void sgx_cgroup_uncharge(struct sgx_cgroup *sgx_cg) { } + +static inline void sgx_cgroup_init(void) { } + +#else /* CONFIG_CGROUP_MISC */ + +struct sgx_cgroup { + struct misc_cg *cg; +}; + +static inline struct sgx_cgroup *sgx_cgroup_from_misc_cg(struct misc_cg *cg) +{ + return (struct sgx_cgroup *)(cg->res[MISC_CG_RES_SGX_EPC].priv); +} + +/** + * sgx_get_current_cg() - get the EPC cgroup of current process. + * + * Returned cgroup has its ref count increased by 1. Caller must call + * sgx_put_cg() to return the reference. + * + * Return: EPC cgroup to which the current task belongs to. + */ +static inline struct sgx_cgroup *sgx_get_current_cg(void) +{ + /* get_current_misc_cg() never returns NULL when Kconfig enabled */ + return sgx_cgroup_from_misc_cg(get_current_misc_cg()); +} + +/** + * sgx_put_cg() - Put the EPC cgroup and reduce its ref count. + * @sgx_cg - EPC cgroup to put. + */ +static inline void sgx_put_cg(struct sgx_cgroup *sgx_cg) +{ + put_misc_cg(sgx_cg->cg); +} + +int sgx_cgroup_try_charge(struct sgx_cgroup *sgx_cg); +void sgx_cgroup_uncharge(struct sgx_cgroup *sgx_cg); +void sgx_cgroup_init(void); + +#endif /* CONFIG_CGROUP_MISC */ + +#endif /* _SGX_EPC_CGROUP_H_ */ diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index d219f14365d4..d482ae7fdabf 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include "driver.h" #include "encl.h" #include "encls.h" +#include "epc_cgroup.h" struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS]; static int sgx_nr_epc_sections; @@ -558,7 +560,16 @@ int sgx_unmark_page_reclaimable(struct sgx_epc_page *page) */ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, enum sgx_reclaim reclaim) { + struct sgx_cgroup *sgx_cg; struct sgx_epc_page *page; + int ret; + + sgx_cg = sgx_get_current_cg(); + ret = sgx_cgroup_try_charge(sgx_cg); + if (ret) { + sgx_put_cg(sgx_cg); + return ERR_PTR(ret); + } for ( ; ; ) { page = __sgx_alloc_epc_page(); @@ -567,8 +578,10 @@ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, enum sgx_reclaim reclaim) break; } - if (list_empty(&sgx_active_page_list)) - return ERR_PTR(-ENOMEM); + if (list_empty(&sgx_active_page_list)) { + page = ERR_PTR(-ENOMEM); + break; + } if (reclaim == SGX_NO_RECLAIM) { page = ERR_PTR(-EBUSY); @@ -584,6 +597,15 @@ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, enum sgx_reclaim reclaim) cond_resched(); } + if (!IS_ERR(page)) { + WARN_ON_ONCE(sgx_epc_page_get_cgroup(page)); + /* sgx_put_cg() in sgx_free_epc_page() */ + sgx_epc_page_set_cgroup(page, sgx_cg); + } else { + sgx_cgroup_uncharge(sgx_cg); + sgx_put_cg(sgx_cg); + } + if (sgx_should_reclaim(SGX_NR_LOW_PAGES)) wake_up(&ksgxd_waitq); @@ -602,8 +624,16 @@ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, enum sgx_reclaim reclaim) void sgx_free_epc_page(struct sgx_epc_page *page) { struct sgx_epc_section *section = &sgx_epc_sections[page->section]; + struct sgx_cgroup *sgx_cg = sgx_epc_page_get_cgroup(page); struct sgx_numa_node *node = section->node; + /* sgx_cg could be NULL if called from __sgx_sanitize_pages() */ + if (sgx_cg) { + sgx_cgroup_uncharge(sgx_cg); + sgx_put_cg(sgx_cg); + sgx_epc_page_set_cgroup(page, NULL); + } + spin_lock(&node->lock); page->owner = NULL; @@ -643,6 +673,8 @@ static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size, section->pages[i].flags = 0; section->pages[i].owner = NULL; section->pages[i].poison = 0; + sgx_epc_page_set_cgroup(§ion->pages[i], NULL); + list_add_tail(§ion->pages[i].list, &sgx_dirty_page_list); } @@ -787,6 +819,7 @@ static void __init arch_update_sysfs_visibility(int nid) {} static bool __init sgx_page_cache_init(void) { u32 eax, ebx, ecx, edx, type; + u64 capacity = 0; u64 pa, size; int nid; int i; @@ -837,6 +870,7 @@ static bool __init sgx_page_cache_init(void) sgx_epc_sections[i].node = &sgx_numa_nodes[nid]; sgx_numa_nodes[nid].size += size; + capacity += size; sgx_nr_epc_sections++; } @@ -846,6 +880,8 @@ static bool __init sgx_page_cache_init(void) return false; } + misc_cg_set_capacity(MISC_CG_RES_SGX_EPC, capacity); + return true; } @@ -942,6 +978,9 @@ static int __init sgx_init(void) if (sgx_vepc_init() && ret) goto err_provision; + /* Setup cgroup if either the native or vepc driver is active */ + sgx_cgroup_init(); + return 0; err_provision: diff --git a/arch/x86/kernel/cpu/sgx/sgx.h b/arch/x86/kernel/cpu/sgx/sgx.h index ca34cd4f58ac..fae8eef10232 100644 --- a/arch/x86/kernel/cpu/sgx/sgx.h +++ b/arch/x86/kernel/cpu/sgx/sgx.h @@ -39,14 +39,35 @@ enum sgx_reclaim { SGX_DO_RECLAIM }; +struct sgx_cgroup; + struct sgx_epc_page { unsigned int section; u16 flags; u16 poison; struct sgx_encl_page *owner; struct list_head list; +#ifdef CONFIG_CGROUP_MISC + struct sgx_cgroup *sgx_cg; +#endif }; +static inline void sgx_epc_page_set_cgroup(struct sgx_epc_page *page, struct sgx_cgroup *cg) +{ +#ifdef CONFIG_CGROUP_MISC + page->sgx_cg = cg; +#endif +} + +static inline struct sgx_cgroup *sgx_epc_page_get_cgroup(struct sgx_epc_page *page) +{ +#ifdef CONFIG_CGROUP_MISC + return page->sgx_cg; +#else + return NULL; +#endif +} + /* * Contains the tracking data for NUMA nodes having EPC pages. Most importantly, * the free page list local to the node is stored here. diff --git a/include/linux/misc_cgroup.h b/include/linux/misc_cgroup.h index 440ed2bb8053..c9b47a5e966a 100644 --- a/include/linux/misc_cgroup.h +++ b/include/linux/misc_cgroup.h @@ -46,11 +46,13 @@ struct misc_res_ops { * @max: Maximum limit on the resource. * @usage: Current usage of the resource. * @events: Number of times, the resource limit exceeded. + * @priv: resource specific data. */ struct misc_res { u64 max; atomic64_t usage; atomic64_t events; + void *priv; }; /** -- 2.25.1