[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210719182009.1409895-3-tony.luck@intel.com>
Date: Mon, 19 Jul 2021 11:20:05 -0700
From: Tony Luck <tony.luck@...el.com>
To: Sean Christopherson <seanjc@...gle.com>,
Jarkko Sakkinen <jarkko.sakkinen@...el.com>,
Dave Hansen <dave.hansen@...el.com>
Cc: x86@...nel.org, linux-kernel@...r.kernel.org,
Tony Luck <tony.luck@...el.com>
Subject: [PATCH v2 2/6] x86/sgx: Add infrastructure to identify SGX EPC pages
X86 machine check architecture reports a physical address when there
is a memory error. Handling that error requires a method to determine
whether the physical address reported is in any of the areas reserved
for EPC pages by BIOS.
Add an end_phys_addr field to the sgx_epc_section structure and a
new function sgx_paddr_to_page() that searches all such structures
and returns the struct sgx_epc_page pointer if the address is an EPC
page. This function is only intended for use within SGX code.
Export a function sgx_is_epc_page() that simply reports whether an
address is an EPC page for use elsewhere in the kernel.
Signed-off-by: Tony Luck <tony.luck@...el.com>
---
arch/x86/kernel/cpu/sgx/main.c | 24 ++++++++++++++++++++++++
arch/x86/kernel/cpu/sgx/sgx.h | 1 +
2 files changed, 25 insertions(+)
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index d61bc1f635a1..41753f81a071 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -654,6 +654,7 @@ static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
}
section->phys_addr = phys_addr;
+ section->end_phys_addr = phys_addr + size - 1;
for (i = 0; i < nr_pages; i++) {
section->pages[i].section = index;
@@ -665,6 +666,29 @@ static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
return true;
}
+static struct sgx_epc_page *sgx_paddr_to_page(u64 paddr)
+{
+ struct sgx_epc_section *section;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sgx_epc_sections); i++) {
+ section = &sgx_epc_sections[i];
+
+ if (paddr < section->phys_addr || paddr > section->end_phys_addr)
+ continue;
+
+ return §ion->pages[PFN_DOWN(paddr - section->phys_addr)];
+ }
+
+ return NULL;
+}
+
+bool sgx_is_epc_page(u64 paddr)
+{
+ return !!sgx_paddr_to_page(paddr);
+}
+EXPORT_SYMBOL_GPL(sgx_is_epc_page);
+
/**
* A section metric is concatenated in a way that @low bits 12-31 define the
* bits 12-31 of the metric and @high bits 0-19 define the bits 32-51 of the
diff --git a/arch/x86/kernel/cpu/sgx/sgx.h b/arch/x86/kernel/cpu/sgx/sgx.h
index 4e1a410b8a62..226b081a4d05 100644
--- a/arch/x86/kernel/cpu/sgx/sgx.h
+++ b/arch/x86/kernel/cpu/sgx/sgx.h
@@ -50,6 +50,7 @@ struct sgx_numa_node {
*/
struct sgx_epc_section {
unsigned long phys_addr;
+ unsigned long end_phys_addr;
void *virt_addr;
struct sgx_epc_page *pages;
struct sgx_numa_node *node;
--
2.29.2
Powered by blists - more mailing lists