linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Martin Fernandez <martin.fernandez@eclypsium.com>
To: linux-efi@vger.kernel.org, platform-driver-x86@vger.kernel.org
Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	x86@kernel.org, hpa@zytor.com, dave.hansen@linux.intel.com,
	luto@kernel.org, peterz@infradead.org, ardb@kernel.org,
	dvhart@infradead.org, andy@infradead.org,
	gregkh@linuxfoundation.org, rafael@kernel.org,
	martin.fernandez@eclypsium.com, daniel.gutson@eclypsium.com,
	hughsient@gmail.com
Subject: [PATCH 1/1] x86: Export information about hardware memory encryption to sysfs
Date: Fri, 10 Sep 2021 18:33:37 -0300	[thread overview]
Message-ID: <20210910213337.48017-2-martin.fernandez@eclypsium.com> (raw)
In-Reply-To: <20210910213337.48017-1-martin.fernandez@eclypsium.com>

Show on each local memory node if all system memory is flagged with
EFI_MEMORY_CPU_CRYPTO

Reviewed-by: Richard Hughes <hughsient@gmail.com>
Signed-off-by: Martin Fernandez <martin.fernandez@eclypsium.com>
---
 Documentation/ABI/testing/sysfs-devices-node | 11 +++
 arch/x86/include/asm/numa.h                  |  2 +
 arch/x86/mm/numa.c                           |  5 ++
 arch/x86/mm/numa_emulation.c                 |  2 +-
 arch/x86/platform/efi/efi.c                  | 27 +++++++
 drivers/base/node.c                          | 80 +++++++++++++++++++-
 include/linux/efi.h                          |  7 ++
 include/linux/node.h                         |  5 ++
 8 files changed, 137 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-devices-node

diff --git a/Documentation/ABI/testing/sysfs-devices-node b/Documentation/ABI/testing/sysfs-devices-node
new file mode 100644
index 000000000000..8578e49c328a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-node
@@ -0,0 +1,11 @@
+What:		/sys/devices/system/node/nodeX/crypto_capable
+Date:		September 2021
+Contact:	Martin Fernandez <martin.fernandez@eclypsium.com>
+Users:		fwupd
+Description:
+		This value is 1 if all system memory is marked with
+		EFI_MEMORY_CPU_CRYPTO, indicating that the system
+		memory is capable of being protected with the CPU’s
+		memory cryptographic capabilities. It is 0
+		otherwise. This attribute will only be available if
+		node X is local.
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h
index e3bae2b60a0d..fc2e8c2e0d14 100644
--- a/arch/x86/include/asm/numa.h
+++ b/arch/x86/include/asm/numa.h
@@ -20,6 +20,8 @@
 #define NODE_MIN_SIZE (4*1024*1024)
 
 extern int numa_off;
+extern bool dummy_numa;
+extern int emu_nid_to_phys[];
 
 /*
  * __apicid_to_node[] stores the raw mapping between physical apicid and
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index a1b5c71099e6..f2b70b6de87f 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -20,6 +20,7 @@
 #include "numa_internal.h"
 
 int numa_off;
+bool dummy_numa;
 nodemask_t numa_nodes_parsed __initdata;
 
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
@@ -712,6 +713,8 @@ static int __init dummy_numa_init(void)
 	node_set(0, numa_nodes_parsed);
 	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
 
+	dummy_numa = true;
+
 	return 0;
 }
 
@@ -724,6 +727,8 @@ static int __init dummy_numa_init(void)
  */
 void __init x86_numa_init(void)
 {
+	dummy_numa = false;
+
 	if (!numa_off) {
 #ifdef CONFIG_ACPI_NUMA
 		if (!numa_init(x86_acpi_numa_init))
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 737491b13728..d92edbede560 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -10,7 +10,7 @@
 
 #include "numa_internal.h"
 
-static int emu_nid_to_phys[MAX_NUMNODES];
+int emu_nid_to_phys[MAX_NUMNODES];
 static char *emu_cmdline __initdata;
 
 int __init numa_emu_cmdline(char *str)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 147c30a81f15..778a2d21d0d0 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -441,6 +441,31 @@ static int __init efi_config_init(const efi_config_table_type_t *arch_tables)
 	return ret;
 }
 
+enum efi_mem_crypto_t efi_mem_crypto = EFI_MEM_ENCRYPTION_NOT_CAPABLE;
+
+static void __init efi_set_mem_crypto(void)
+{
+	efi_memory_desc_t *md;
+
+	efi_mem_crypto = EFI_MEM_ENCRYPTION_CAPABLE;
+
+	for_each_efi_memory_desc(md) {
+		switch (md->type) {
+		/* System memory after ExitBootServices */
+		case EFI_LOADER_CODE:
+		case EFI_LOADER_DATA:
+		case EFI_BOOT_SERVICES_CODE:
+		case EFI_BOOT_SERVICES_DATA:
+		case EFI_CONVENTIONAL_MEMORY:
+		case EFI_ACPI_RECLAIM_MEMORY:
+			if (!(md->attribute & EFI_MEMORY_CPU_CRYPTO)) {
+				efi_mem_crypto = EFI_MEM_ENCRYPTION_NOT_CAPABLE;
+				return;
+			}
+		}
+	}
+}
+
 void __init efi_init(void)
 {
 	if (IS_ENABLED(CONFIG_X86_32) &&
@@ -494,6 +519,8 @@ void __init efi_init(void)
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 	efi_clean_memmap();
 
+	efi_set_mem_crypto();
+
 	if (efi_enabled(EFI_DBG))
 		efi_print_memmap();
 }
diff --git a/drivers/base/node.c b/drivers/base/node.c
index be16bbff11cc..c01ba33f2054 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
+#include <linux/efi.h>
 
 static struct bus_type node_subsys = {
 	.name = "node",
@@ -68,6 +69,15 @@ static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj,
 
 static BIN_ATTR_RO(cpulist, 0);
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_EFI)
+static ssize_t crypto_capable_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "%d\n", efi_mem_crypto);
+}
+static DEVICE_ATTR_RO(crypto_capable);
+#endif
+
 /**
  * struct node_access_nodes - Access class device to hold user visible
  * 			      relationships to other nodes.
@@ -584,6 +594,23 @@ static const struct attribute_group *node_dev_groups[] = {
 	NULL
 };
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_EFI)
+static struct attribute *node_dev_crypto_attrs[] = {
+	&dev_attr_crypto_capable.attr,
+	NULL
+};
+
+static const struct attribute_group node_dev_crypto_group = {
+	.attrs = node_dev_crypto_attrs,
+};
+
+static const struct attribute_group *node_dev_crypto_groups[] = {
+	&node_dev_group,
+	&node_dev_crypto_group,
+	NULL
+};
+#endif
+
 #ifdef CONFIG_HUGETLBFS
 /*
  * hugetlbfs per node attributes registration interface:
@@ -644,6 +671,21 @@ static void node_device_release(struct device *dev)
 	kfree(node);
 }
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_EFI)
+static const struct attribute_group **select_attr_groups(bool cpu_local)
+{
+	if (cpu_local)
+		return node_dev_crypto_groups;
+	else
+		return node_dev_groups;
+}
+#else
+static const struct attribute_group **select_attr_groups(bool cpu_local)
+{
+	return node_dev_groups;
+}
+#endif
+
 /*
  * register_node - Setup a sysfs device for a node.
  * @num - Node number to use when creating the device.
@@ -657,7 +699,8 @@ static int register_node(struct node *node, int num)
 	node->dev.id = num;
 	node->dev.bus = &node_subsys;
 	node->dev.release = node_device_release;
-	node->dev.groups = node_dev_groups;
+	node->dev.groups = select_attr_groups(node->cpu_local);
+
 	error = device_register(&node->dev);
 
 	if (error)
@@ -974,6 +1017,39 @@ static void init_node_hugetlb_work(int nid) { }
 
 #endif
 
+#ifdef CONFIG_NUMA
+#ifdef CONFIG_NUMA_EMU
+static int get_real_nid(int nid)
+{
+	return emu_nid_to_phys[nid];
+}
+#else
+static int get_real_nid(int nid)
+{
+	return nid;
+}
+#endif
+
+static void set_cpu_local(int nid)
+{
+	int real_nid;
+	bool cpu_local;
+
+	real_nid = get_real_nid(nid);
+
+#ifdef CONFIG_ACPI_NUMA
+	cpu_local =
+		dummy_numa ? real_nid == 0 : node_to_pxm(real_nid) != PXM_INVAL;
+#else
+	cpu_local = real_nid == 0;
+#endif
+
+	node_devices[nid]->cpu_local = cpu_local;
+}
+#else
+#define set_cpu_local(nid)
+#endif /* CONFIG_NUMA */
+
 int __register_one_node(int nid)
 {
 	int error;
@@ -983,6 +1059,8 @@ int __register_one_node(int nid)
 	if (!node_devices[nid])
 		return -ENOMEM;
 
+	set_cpu_local(nid);
+
 	error = register_node(node_devices[nid], nid);
 
 	/* link cpu under this node */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 6b5d36babfcc..0d9b304b204e 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1282,4 +1282,11 @@ static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find(
 }
 #endif
 
+enum efi_mem_crypto_t {
+	EFI_MEM_ENCRYPTION_NOT_CAPABLE,
+	EFI_MEM_ENCRYPTION_CAPABLE,
+};
+
+extern enum efi_mem_crypto_t efi_mem_crypto;
+
 #endif /* _LINUX_EFI_H */
diff --git a/include/linux/node.h b/include/linux/node.h
index 8e5a29897936..6df1f90480f2 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -19,6 +19,8 @@
 #include <linux/cpumask.h>
 #include <linux/list.h>
 #include <linux/workqueue.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_numa.h>
 
 /**
  * struct node_hmem_attrs - heterogeneous memory performance attributes
@@ -92,6 +94,9 @@ struct node {
 	struct list_head cache_attrs;
 	struct device *cache_dev;
 #endif
+#ifdef CONFIG_NUMA
+	bool cpu_local;
+#endif
 };
 
 struct memory_block;
-- 
2.30.2


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.













  reply	other threads:[~2021-09-10 21:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-10 21:33 [PATCH 0/1] [RFC] " Martin Fernandez
2021-09-10 21:33 ` Martin Fernandez [this message]
2021-09-10 21:42   ` [PATCH 1/1] " Dave Hansen
2021-09-10 21:44 ` [PATCH 0/1] [RFC] " Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210910213337.48017-2-martin.fernandez@eclypsium.com \
    --to=martin.fernandez@eclypsium.com \
    --cc=andy@infradead.org \
    --cc=ardb@kernel.org \
    --cc=bp@alien8.de \
    --cc=daniel.gutson@eclypsium.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dvhart@infradead.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=hughsient@gmail.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --subject='Re: [PATCH 1/1] x86: Export information about hardware memory encryption to sysfs' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).