diff options
author | Khalid Aziz <khalid.aziz@oracle.com> | 2018-02-23 15:46:41 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-18 07:38:48 -0700 |
commit | 74a04967482faa7144b93dae3b2e913870dd421c (patch) | |
tree | 387f2497cfd053d99504a00ff8ccce0dd5fbd647 /arch/sparc/mm/tsb.c | |
parent | a4602b62d9fdea41412ba765bbf32ecfc2b6a94c (diff) | |
download | linux-next-74a04967482faa7144b93dae3b2e913870dd421c.tar.gz |
sparc64: Add support for ADI (Application Data Integrity)
ADI is a new feature supported on SPARC M7 and newer processors to allow
hardware to catch rogue accesses to memory. ADI is supported for data
fetches only and not instruction fetches. An app can enable ADI on its
data pages, set version tags on them and use versioned addresses to
access the data pages. Upper bits of the address contain the version
tag. On M7 processors, upper four bits (bits 63-60) contain the version
tag. If a rogue app attempts to access ADI enabled data pages, its
access is blocked and processor generates an exception. Please see
Documentation/sparc/adi.txt for further details.
This patch extends mprotect to enable ADI (TSTATE.mcde), enable/disable
MCD (Memory Corruption Detection) on selected memory ranges, enable
TTE.mcd in PTEs, return ADI parameters to userspace and save/restore ADI
version tags on page swap out/in or migration. ADI is not enabled by
default for any task. A task must explicitly enable ADI on a memory
range and set version tag for ADI to be effective for the task.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
Reviewed-by: Anthony Yznaga <anthony.yznaga@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm/tsb.c')
-rw-r--r-- | arch/sparc/mm/tsb.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 75a04c1a2383..f5edc28aa3a5 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -546,6 +546,9 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) mm->context.sparc64_ctx_val = 0UL; + mm->context.tag_store = NULL; + spin_lock_init(&mm->context.tag_lock); + #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) /* We reset them to zero because the fork() page copying * will re-increment the counters as the parent PTEs are @@ -611,4 +614,22 @@ void destroy_context(struct mm_struct *mm) } spin_unlock_irqrestore(&ctx_alloc_lock, flags); + + /* If ADI tag storage was allocated for this task, free it */ + if (mm->context.tag_store) { + tag_storage_desc_t *tag_desc; + unsigned long max_desc; + unsigned char *tags; + + tag_desc = mm->context.tag_store; + max_desc = PAGE_SIZE/sizeof(tag_storage_desc_t); + for (i = 0; i < max_desc; i++) { + tags = tag_desc->tags; + tag_desc->tags = NULL; + kfree(tags); + tag_desc++; + } + kfree(mm->context.tag_store); + mm->context.tag_store = NULL; + } } |