Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1707972 > unrolled thread
| Started by | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| First post | 2017-08-09 23:30 +0200 |
| Last post | 2017-08-09 23:30 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v7 0/9] Application Data Integrity feature introduced by SPARC M7 Khalid Aziz <khalid.aziz@oracle.com> - 2017-08-09 23:30 +0200
[PATCH v7 2/9] mm, swap: Add infrastructure for saving page metadata on swap Khalid Aziz <khalid.aziz@oracle.com> - 2017-08-09 23:30 +0200
[PATCH v7 4/9] sparc64: Add HV fault type handlers for ADI related faults Khalid Aziz <khalid.aziz@oracle.com> - 2017-08-09 23:30 +0200
[PATCH v7 1/9] signals, sparc: Add signal codes for ADI violations Khalid Aziz <khalid.aziz@oracle.com> - 2017-08-09 23:30 +0200
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-08-09 23:30 +0200 |
| Subject | [PATCH v7 0/9] Application Data Integrity feature introduced by SPARC M7 |
| Message-ID | <ucGI9-4oh-7@gated-at.bofh.it> |
SPARC M7 processor adds additional metadata for memory address space that can be used to secure access to regions of memory. This additional metadata is implemented as a 4-bit tag attached to each cacheline size block of memory. A task can set a tag on any number of such blocks. Access to such block is granted only if the virtual address used to access that block of memory has the tag encoded in the uppermost 4 bits of VA. Since sparc processor does not implement all 64 bits of VA, top 4 bits are available for ADI tags. Any mismatch between tag encoded in VA and tag set on the memory block results in a trap. Tags are verified in the VA presented to the MMU and tags are associated with the physical page VA maps on to. If a memory page is swapped out and page frame gets reused for another task, the tags are lost and hence must be saved when swapping or migrating the page. A userspace task enables ADI through mprotect(). This patch series adds a page protection bit PROT_ADI and a corresponding VMA flag VM_SPARC_ADI. VM_SPARC_ADI is used to trigger setting TTE.mcd bit in the sparc pte that enables ADI checking on the corresponding page. MMU validates the tag embedded in VA for every page that has TTE.mcd bit set in its pte. After enabling ADI on a memory range, the userspace task can set ADI version tags using stxa instruction with ASI_MCD_PRIMARY or ASI_MCD_ST_BLKINIT_PRIMARY ASI. Once userspace task calls mprotect() with PROT_ADI, kernel takes following overall steps: 1. Find the VMAs covering the address range passed in to mprotect and set VM_SPARC_ADI flag. If address range covers a subset of a VMA, the VMA will be split. 2. When a page is allocated for a VA and the VMA covering this VA has VM_SPARC_ADI flag set, set the TTE.mcd bit so MMU will check the vwersion tag. 3. Userspace can now set version tags on the memory it has enabled ADI on. Userspace accesses ADI enabled memory using a virtual address that has the version tag embedded in the high bits. MMU validates this version tag against the actual tag set on the memory. If tag matches, MMU performs the VA->PA translation and access is granted. If there is a mismatch, hypervisor sends a data access exception or precise memory corruption detected exception depending upon whether precise exceptions are enabled or not (controlled by MCDPERR register). Kernel sends SIGSEGV to the task with appropriate si_code. 4. If a page is being swapped out or migrated, kernel must save any ADI tags set on the page. Kernel maintains a page worth of tag storage descriptors. Each descriptors pointsto a tag storage space and the address range it covers. If the page being swapped out or migrated has ADI enabled on it, kernel finds a tag storage descriptor that covers the address range for the page or allocates a new descriptor if none of the existing descriptors cover the address range. Kernel saves tags from the page into the tag storage space descriptor points to. 5. When the page is swapped back in or reinstantiated after migration, kernel restores the version tags on the new physical page by retrieving the original tag from tag storage pointed to by a tag storage descriptor for the virtual address range for new page. User task can disable ADI by calling mprotect() again on the memory range with PROT_ADI bit unset. Kernel clears the VM_SPARC_ADI flag in VMAs, merges adjacent VMAs if necessary, and clears TTE.mcd bit in the corresponding ptes. IOMMU does not support ADI checking. Any version tags embedded in the top bits of VA meant for IOMMU, are cleared and replaced with sign extension of the first non-version tag bit (bit 59 for SPARC M7) for IOMMU addresses. This patch series adds support for this feature in 9 patches: Patch 1/9 Tag mismatch on access by a task results in a trap from hypervisor as data access exception or a precide memory corruption detected exception. As part of handling these exceptions, kernel sends a SIGSEGV to user process with special si_code to indicate which fault occurred. This patch adds three new si_codes to differentiate between various mismatch errors. Patch 2/9 When a page is swapped or migrated, metadata associated with the page must be saved so it can be restored later. This patch adds a new function that saves/restores this metadata when updating pte upon a swap/migration. Patch 3/9 SPARC M7 processor adds new fields to control registers to support ADI feature. It also adds a new exception for precise traps on tag mismatch. This patch adds definitions for the new control register fields, new ASIs for ADI and an exception handler for the precise trap on tag mismatch. Patch 4/9 New hypervisor fault types were added by sparc M7 processor to support ADI feature. This patch adds code to handle these fault types for data access exception handler. Patch 5/9 When ADI is in use for a page and a tag mismatch occurs, processor raises "Memory corruption Detected" trap. This patch adds a handler for this trap. Patch 6/9 ADI usage is governed by ADI properties on a platform. These properties are provided to kernel by firmware. Thsi patch adds new auxiliary vectors that provide these values to userpsace. Patch 7/9 arch_validate_prot() is used to validate the new protection bits asked for by the userspace app. Validating protection bits may need the context of address space the bits are being applied to. One such example is PROT_ADI bit on sparc processor that enables ADI protection on an address range. ADI protection applies only to addresses covered by physical RAM and not other PFN mapped addresses or device addresses. This patch adds "address" to the parameters being passed to arch_validate_prot() to provide that context. Patch 8/9 When protection bits are changed on a page, kernel carries forward all protection bits except for read/write/exec. Additional code was added to allow kernel to clear PKEY bits on x86 but this requirement to clear other bits is not unique to x86. This patch extends the existing code to allow other architectures to clear any other protection bits as well on protection bit change. Patch 9/9 This patch adds support for a user space task to enable ADI and enable tag checking for subsets of its address space. As part of enabling this feature, this patch adds to support manipulation of precise exception for memory corruption detection, adds code to save and restore tags on page swap and migration, and adds code to handle ADI tagged addresses for DMA. Changelog v7: - Patch 1/9: No changes - Patch 2/9: Updated parameters to arch specific swap in/out handlers - Patch 3/9: No changes - Patch 4/9: new patch split off from patch 4/4 in v6 - Patch 5/9: new patch split off from patch 4/4 in v6 - Patch 6/9: new patch split off from patch 4/4 in v6 - Patch 7/9: new patch - Patch 8/9: new patch - Patch 9/9: - Enhanced arch_validate_prot() to enable ADI only on writable addresses backed by physical RAM - Added support for saving/restoring ADI tags for each ADI block size address range on a page on swap in/out - copy ADI tags on COW - Updated values for auxiliary vectors to not conflict with values on other architectures to avoid conflict in glibc - Disable same page merging on ADI enabled pages - Enable ADI only on writable addresses backed by physical RAM - Split parts of patch off into separate patches Changelog v6: - Patch 1/4: No changes - Patch 2/4: No changes - Patch 3/4: Added missing nop in the delay slot in sun4v_mcd_detect_precise - Patch 4/4: Eliminated instructions to read and write PSTATE as well as MCDPER and PMCDPER on every access to userspace addresses by setting PSTATE and PMCDPER correctly upon entry into kernel Changelog v5: - Patch 1/4: No changes - Patch 2/4: Replaced set_swp_pte_at() with new architecture functions arch_do_swap_page() and arch_unmap_one() that suppoprt architecture specific actions to be taken on page swap and migration - Patch 3/4: Fixed indentation issues in assembly code - Patch 4/4: - Fixed indentation issues and instrcuctions in assembly code - Removed CONFIG_SPARC64 from mdesc.c - Changed to maintain state of MCDPER register in thread info flags as opposed to in mm context. MCDPER is a per-thread state and belongs in thread info flag as opposed to mm context which is shared across threads. Added comments to clarify this is a lazily maintained state and must be updated on context switch and copy_process() - Updated code to use the new arch_do_swap_page() and arch_unmap_one() functions Testing: - All functionality was tested with 8K normal pages as well as hugepages using malloc, mmap and shm. - Multiple long duration stress tests were run using hugepages over 2+ months. Normal pages were tested with shorter duration stress tests. - Tested swapping with malloc and shm by reducing max memory and allocating three times the available system memory by active processes using ADI on allocated memory. Ran through multiple hours long runs of this test. - Tested page migration with malloc and shm by migrating data pages of active ADI test process using migratepages, back and forth between two nodes every few seconds over an hour long run. Verified page migration through /proc/<pid>/numa_maps. - Tested COW support using test that forks children that read from ADI enabled pages shared with parent and other children and write to them as well forcing COW. --------- Khalid Aziz (9): signals, sparc: Add signal codes for ADI violations mm, swap: Add infrastructure for saving page metadata as well on swap sparc64: Add support for ADI register fields, ASIs and traps sparc64: Add HV fault type handlers for ADI related faults sparc64: Add handler for "Memory Corruption Detected" trap sparc64: Add auxiliary vectors to report platform ADI properties mm: Add address parameter to arch_validate_prot() mm: Clear arch specific VM flags on protection change sparc64: Add support for ADI (Application Data Integrity) Documentation/sparc/adi.txt | 272 +++++++++++++++++++++++ arch/powerpc/include/asm/mman.h | 2 +- arch/powerpc/kernel/syscalls.c | 2 +- arch/sparc/include/asm/adi.h | 6 + arch/sparc/include/asm/adi_64.h | 45 ++++ arch/sparc/include/asm/elf_64.h | 8 + arch/sparc/include/asm/hypervisor.h | 2 + arch/sparc/include/asm/mman.h | 72 ++++++- arch/sparc/include/asm/mmu_64.h | 17 ++ arch/sparc/include/asm/mmu_context_64.h | 43 ++++ arch/sparc/include/asm/page_64.h | 4 + arch/sparc/include/asm/pgtable_64.h | 48 +++++ arch/sparc/include/asm/thread_info_64.h | 2 +- arch/sparc/include/asm/trap_block.h | 2 + arch/sparc/include/asm/ttable.h | 10 + arch/sparc/include/uapi/asm/asi.h | 5 + arch/sparc/include/uapi/asm/auxvec.h | 10 + arch/sparc/include/uapi/asm/mman.h | 2 + arch/sparc/include/uapi/asm/pstate.h | 10 + arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/adi_64.c | 367 ++++++++++++++++++++++++++++++++ arch/sparc/kernel/entry.h | 3 + arch/sparc/kernel/etrap_64.S | 28 ++- arch/sparc/kernel/head_64.S | 1 + arch/sparc/kernel/mdesc.c | 2 + arch/sparc/kernel/process_64.c | 25 +++ arch/sparc/kernel/setup_64.c | 11 +- arch/sparc/kernel/sun4v_mcd.S | 17 ++ arch/sparc/kernel/traps_64.c | 142 +++++++++++- arch/sparc/kernel/ttable_64.S | 6 +- arch/sparc/kernel/vmlinux.lds.S | 5 + arch/sparc/mm/gup.c | 37 ++++ arch/sparc/mm/hugetlbpage.c | 14 +- arch/sparc/mm/init_64.c | 33 +++ arch/sparc/mm/tsb.c | 21 ++ arch/x86/kernel/signal_compat.c | 2 +- include/asm-generic/pgtable.h | 36 ++++ include/linux/mm.h | 9 + include/linux/mman.h | 2 +- include/uapi/asm-generic/siginfo.h | 5 +- mm/ksm.c | 4 + mm/memory.c | 1 + mm/mprotect.c | 4 +- mm/rmap.c | 13 ++ 44 files changed, 1334 insertions(+), 17 deletions(-) create mode 100644 Documentation/sparc/adi.txt create mode 100644 arch/sparc/include/asm/adi.h create mode 100644 arch/sparc/include/asm/adi_64.h create mode 100644 arch/sparc/kernel/adi_64.c create mode 100644 arch/sparc/kernel/sun4v_mcd.S -- 2.11.0
[toc] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-08-09 23:30 +0200 |
| Subject | [PATCH v7 2/9] mm, swap: Add infrastructure for saving page metadata on swap |
| Message-ID | <ucGIb-4oh-29@gated-at.bofh.it> |
| In reply to | #1707972 |
If a processor supports special metadata for a page, for example ADI
version tags on SPARC M7, this metadata must be saved when the page is
swapped out. The same metadata must be restored when the page is swapped
back in. This patch adds two new architecture specific functions -
arch_do_swap_page() to be called when a page is swapped in, and
arch_unmap_one() to be called when a page is being unmapped for swap
out. These architecture hooks allow page metadata to be saved if the
architecture supports it.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
Acked-by: Jerome Marchand <jmarchan@redhat.com>
---
v6:
- Updated parameter list for arch_do_swap_page() and
arch_unmap_one()
v5:
- Replaced set_swp_pte() function with new architecture
functions arch_do_swap_page() and arch_unmap_one()
include/asm-generic/pgtable.h | 36 ++++++++++++++++++++++++++++++++++++
mm/memory.c | 1 +
mm/rmap.c | 13 +++++++++++++
3 files changed, 50 insertions(+)
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 7dfa767dc680..15668c2470b4 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -392,6 +392,42 @@ static inline int pud_same(pud_t pud_a, pud_t pud_b)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#endif
+#ifndef __HAVE_ARCH_DO_SWAP_PAGE
+/*
+ * Some architectures support metadata associated with a page. When a
+ * page is being swapped out, this metadata must be saved so it can be
+ * restored when the page is swapped back in. SPARC M7 and newer
+ * processors support an ADI (Application Data Integrity) tag for the
+ * page as metadata for the page. arch_do_swap_page() can restore this
+ * metadata when a page is swapped back in.
+ */
+static inline void arch_do_swap_page(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long addr,
+ pte_t pte, pte_t oldpte)
+{
+
+}
+#endif
+
+#ifndef __HAVE_ARCH_UNMAP_ONE
+/*
+ * Some architectures support metadata associated with a page. When a
+ * page is being swapped out, this metadata must be saved so it can be
+ * restored when the page is swapped back in. SPARC M7 and newer
+ * processors support an ADI (Application Data Integrity) tag for the
+ * page as metadata for the page. arch_unmap_one() can save this
+ * metadata on a swap-out of a page.
+ */
+static inline int arch_unmap_one(struct mm_struct *mm,
+ struct vm_area_struct *vma,
+ unsigned long addr,
+ pte_t orig_pte)
+{
+ return 0;
+}
+#endif
+
#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr)
#endif
diff --git a/mm/memory.c b/mm/memory.c
index bb11c474857e..eb92e4f94d3b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2798,6 +2798,7 @@ int do_swap_page(struct vm_fault *vmf)
if (pte_swp_soft_dirty(vmf->orig_pte))
pte = pte_mksoft_dirty(pte);
set_pte_at(vma->vm_mm, vmf->address, vmf->pte, pte);
+ arch_do_swap_page(vma->vm_mm, vma, vmf->address, pte, vmf->orig_pte);
vmf->orig_pte = pte;
if (page == swapcache) {
do_page_add_anon_rmap(page, vma, vmf->address, exclusive);
diff --git a/mm/rmap.c b/mm/rmap.c
index d405f0e0ee96..5ff2a7943c57 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1399,6 +1399,12 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
(flags & TTU_MIGRATION)) {
swp_entry_t entry;
pte_t swp_pte;
+
+ if (arch_unmap_one(mm, vma, address, pteval) < 0) {
+ set_pte_at(mm, address, pvmw.pte, pteval);
+ ret = false;
+ page_vma_mapped_walk_done(&pvmw);
+ break;
/*
* Store the pfn of the page in a special migration
* pte. do_swap_page() will wait until the migration
@@ -1410,6 +1416,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
if (pte_soft_dirty(pteval))
swp_pte = pte_swp_mksoft_dirty(swp_pte);
set_pte_at(mm, address, pvmw.pte, swp_pte);
+ }
} else if (PageAnon(page)) {
swp_entry_t entry = { .val = page_private(subpage) };
pte_t swp_pte;
@@ -1448,6 +1455,12 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
page_vma_mapped_walk_done(&pvmw);
break;
}
+ if (arch_unmap_one(mm, vma, address, pteval) < 0) {
+ set_pte_at(mm, address, pvmw.pte, pteval);
+ ret = false;
+ page_vma_mapped_walk_done(&pvmw);
+ break;
+ }
if (list_empty(&mm->mmlist)) {
spin_lock(&mmlist_lock);
if (list_empty(&mm->mmlist))
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-08-09 23:30 +0200 |
| Subject | [PATCH v7 4/9] sparc64: Add HV fault type handlers for ADI related faults |
| Message-ID | <ucGIb-4oh-33@gated-at.bofh.it> |
| In reply to | #1707972 |
ADI (Application Data Integrity) feature on M7 and newer processors
adds new fault types for hypervisor - Invalid ASI and MCD disabled.
This patch expands data access exception handler to handle these
faults.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
---
v7:
- new patch split off from patch 4/4 in v6
arch/sparc/kernel/traps_64.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 88eed0dc3faf..88c96d349f2f 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -352,12 +352,35 @@ void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsig
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
- info.si_signo = SIGSEGV;
+ /* MCD (Memory Corruption Detection) disabled trap (TT=0x19) in HV
+ * is vectored thorugh data access exception trap with fault type
+ * set to HV_FAULT_TYPE_MCD_DIS. Check for MCD disabled trap.
+ * Accessing an address with invalid ASI for the address, for
+ * example setting an ADI tag on an address with ASI_MCD_PRIMARY
+ * when TTE.mcd is not set for the VA, is also vectored into
+ * kerbel by HV as data access exception with fault type set to
+ * HV_FAULT_TYPE_INV_ASI.
+ */
info.si_errno = 0;
- info.si_code = SEGV_MAPERR;
info.si_addr = (void __user *) addr;
info.si_trapno = 0;
- force_sig_info(SIGSEGV, &info, current);
+ switch (type) {
+ case HV_FAULT_TYPE_INV_ASI:
+ info.si_signo = SIGILL;
+ info.si_code = ILL_ILLADR;
+ force_sig_info(SIGILL, &info, current);
+ break;
+ case HV_FAULT_TYPE_MCD_DIS:
+ info.si_signo = SIGSEGV;
+ info.si_code = SEGV_ACCADI;
+ force_sig_info(SIGSEGV, &info, current);
+ break;
+ default:
+ info.si_signo = SIGSEGV;
+ info.si_code = SEGV_MAPERR;
+ force_sig_info(SIGSEGV, &info, current);
+ break;
+ }
}
void sun4v_data_access_exception_tl1(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx)
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Khalid Aziz <khalid.aziz@oracle.com> |
|---|---|
| Date | 2017-08-09 23:30 +0200 |
| Subject | [PATCH v7 1/9] signals, sparc: Add signal codes for ADI violations |
| Message-ID | <ucGIb-4oh-31@gated-at.bofh.it> |
| In reply to | #1707972 |
SPARC M7 processor introduces a new feature - Application Data
Integrity (ADI). ADI allows MMU to catch rogue accesses to memory.
When a rogue access occurs, MMU blocks the access and raises an
exception. In response to the exception, kernel sends the offending
task a SIGSEGV with si_code that indicates the nature of exception.
This patch adds three new signal codes specific to ADI feature:
1. ADI is not enabled for the address and task attempted to access
memory using ADI
2. Task attempted to access memory using wrong ADI tag and caused
a deferred exception.
3. Task attempted to access memory using wrong ADI tag and caused
a precise exception.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
---
arch/x86/kernel/signal_compat.c | 2 +-
include/uapi/asm-generic/siginfo.h | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c
index 71beb28600d4..e6e0b50230c3 100644
--- a/arch/x86/kernel/signal_compat.c
+++ b/arch/x86/kernel/signal_compat.c
@@ -26,7 +26,7 @@ static inline void signal_compat_build_tests(void)
*/
BUILD_BUG_ON(NSIGILL != 8);
BUILD_BUG_ON(NSIGFPE != 8);
- BUILD_BUG_ON(NSIGSEGV != 4);
+ BUILD_BUG_ON(NSIGSEGV != 7);
BUILD_BUG_ON(NSIGBUS != 5);
BUILD_BUG_ON(NSIGTRAP != 4);
BUILD_BUG_ON(NSIGCHLD != 6);
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 1abaf62c86fc..24468643ee9d 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -213,7 +213,10 @@ typedef struct siginfo {
#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */
#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */
#define SEGV_PKUERR (__SI_FAULT|4) /* failed protection key checks */
-#define NSIGSEGV 4
+#define SEGV_ACCADI (__SI_FAULT|5) /* ADI not enabled for mapped object */
+#define SEGV_ADIDERR (__SI_FAULT|6) /* Disrupting MCD error */
+#define SEGV_ADIPERR (__SI_FAULT|7) /* Precise MCD exception */
+#define NSIGSEGV 7
/*
* SIGBUS si_codes
--
2.11.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web