Re: [PATCH v12 00/11] Application Data Integrity feature introduced by SPARC M7

2018-03-19 Thread Khalid Aziz

On 03/18/2018 09:08 AM, David Miller wrote:

In uapi/asm/auxvec.h you conditionalize the ADI aux vectors on
CONFIG_SPARC64.

That's not correct, you should never control user facing definitions
based upon kernel configuration.

Also, both 32-bit and 64-bit applications running on ADI capable
machines want to compile against and use this informaiton.

So please remove these CPP checks.



Hi Dave,

That makes sense. I will send a patch to remove these.

Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-03-05 Thread Khalid Aziz

On 03/05/2018 02:31 PM, Dave Hansen wrote:

On 03/05/2018 01:14 PM, Khalid Aziz wrote:

Are you suggesting that vma returned by find_vma() could be split or
merged underneath me if I do not hold mmap_sem and thus make the flag
check invalid? If so, that is a good point.


This part does make me think that this code hasn't been tested very
thoroughly.  Could you describe the testing that you have done?  For MPX
and protection keys, I added something to tools/testing/selftests/x86,
for instance.


This code was tested by a QA team and I ran a number of tests myself. I 
wrote tests to exercise all of the API, induce exceptions for 
invalid/illegal accesses and swapping was tested by allocating memory 
2-4 times of the system RAM available across 4-8 threads and 
reading/writing to this memory with ADI enabled. QA team wrote unit 
tests to test each API with valid and invalid combinations of arguments 
to the API. Stress tests that allocate and free ADI tagged memory were 
also run. A version of database server was created that uses ADI tagged 
memory for in-memory copy of database to test database workload. 100's 
of hours of tests were run across these tests over the last 1+ year 
these patches have been under review for. Cover letter includes 
description of most of these tests. This code has held up through all of 
these tests. It is entirely feasible some race conditions have not been 
uncovered yet, just like any other piece of software. Pulling this code 
into mainline kernel and having lot more people exercise this code will 
help shake out any remaining issues.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-03-05 Thread Khalid Aziz

On 03/05/2018 02:26 PM, Dave Hansen wrote:

On 02/21/2018 09:15 AM, Khalid Aziz wrote:

+tag_storage_desc_t *alloc_tag_store(struct mm_struct *mm,
+   struct vm_area_struct *vma,
+   unsigned long addr)

...

+   tags = kzalloc(size, GFP_NOWAIT|__GFP_NOWARN);
+   if (tags == NULL) {
+   tag_desc->tag_users = 0;
+   tag_desc = NULL;
+   goto out;
+   }
+   tag_desc->start = addr;
+   tag_desc->tags = tags;
+   tag_desc->end = end_addr;
+
+out:
+   spin_unlock_irqrestore(>context.tag_lock, flags);
+   return tag_desc;
+}


OK, sorry, I missed this.  I do see that you now have per-ADI-block tag
storage and it is not per-page.

How big can this storage get, btw?  Superficially it seems like it might
be able to be gigantic for a large, sparse VMA.



Tags are stored only for the pages being swapped out, not for the pages 
in entire vma. Each tag storage page can hold tags for 128 pages (each 
page has 128 4-bit tags, hence 64 bytes are needed to store tags for an 
entire page allowing each page to store tags for 128 pages). Sparse VMA 
does not cause any problems since holes do not have corresponding pages 
that will be swapped out. Tag storage pages are freed once all the pages 
they store tags for have been swapped back in, except for a small number 
of pages (maximum of 8) marked for emergency tag storage.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-03-05 Thread Khalid Aziz

On 03/05/2018 12:22 PM, Dave Hansen wrote:

On 02/21/2018 09:15 AM, Khalid Aziz wrote:

+#define arch_validate_prot(prot, addr) sparc_validate_prot(prot, addr)
+static inline int sparc_validate_prot(unsigned long prot, unsigned long addr)
+{
+   if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI))
+   return 0;
+   if (prot & PROT_ADI) {
+   if (!adi_capable())
+   return 0;
+
+   if (addr) {
+   struct vm_area_struct *vma;
+
+   vma = find_vma(current->mm, addr);
+   if (vma) {
+   /* ADI can not be enabled on PFN
+* mapped pages
+*/
+   if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
+   return 0;


You don't hold mmap_sem here.  How can this work?



Are you suggesting that vma returned by find_vma() could be split or 
merged underneath me if I do not hold mmap_sem and thus make the flag 
check invalid? If so, that is a good point.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-02-23 Thread Khalid Aziz

On 02/23/2018 11:57 AM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Fri, 23 Feb 2018 11:51:25 -0700


On 02/22/2018 07:50 PM, kbuild test robot wrote:

Hi Khalid,
I love your patch! Yet something to improve:
[auto build test ERROR on sparc-next/master]
[also build test ERROR on v4.16-rc2]
[cannot apply to next-20180222]
[if your patch is applied to the wrong git tree, please drop us a note
to help improve the system]
url:
https://github.com/0day-ci/linux/commits/Khalid-Aziz/Application-Data-Integrity-feature-introduced-by-SPARC-M7/20180223-071725
base:
https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git
master
config: sparc64-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
  wget
  
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
  -O ~/bin/make.cross
  chmod +x ~/bin/make.cross
  # save the attached .config to linux build tree
  make.cross ARCH=sparc64
All error/warnings (new ones prefixed by >>):


Hi Dave,

Including linux/sched.h in arch/sparc/include/asm/mmu_context.h should
eliminate these build warnings. My gcc version 6.2.1 does not report
these errors. Build bot is using 7.2.0.

I can add a patch 12 to add the include, revise patch 10 or you can
add the include in your tree. Let me know how you would prefer to
resolve this.


You need to update patch #10 so that your patch series is fully
bisectable.


Hi Dave,

That sounds like the right thing to do. I am updating patch 10 and will 
send out v13 for patch 10/11. Rest of the series is unchanged but I can 
send the whole series if you prefer that.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-02-23 Thread Khalid Aziz

On 02/22/2018 07:50 PM, kbuild test robot wrote:

Hi Khalid,

I love your patch! Yet something to improve:

[auto build test ERROR on sparc-next/master]
[also build test ERROR on v4.16-rc2]
[cannot apply to next-20180222]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Khalid-Aziz/Application-Data-Integrity-feature-introduced-by-SPARC-M7/20180223-071725
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git 
master
config: sparc64-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
 wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=sparc64

All error/warnings (new ones prefixed by >>):


Hi Dave,

Including linux/sched.h in arch/sparc/include/asm/mmu_context.h should 
eliminate these build warnings. My gcc version 6.2.1 does not report 
these errors. Build bot is using 7.2.0.


I can add a patch 12 to add the include, revise patch 10 or you can add 
the include in your tree. Let me know how you would prefer to resolve this.


Thanks,
Khalid



In file included from arch/sparc/include/asm/mmu_context.h:5:0,
 from include/linux/mmu_context.h:5,
 from drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h:29,
 from drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c:23:
arch/sparc/include/asm/mmu_context_64.h: In function 
'arch_start_context_switch':

arch/sparc/include/asm/mmu_context_64.h:157:4: error: implicit declaration of 
function 'set_tsk_thread_flag'; did you mean 'set_ti_thread_flag'? 
[-Werror=implicit-function-declaration]

set_tsk_thread_flag(prev, TIF_MCDPER);
^~~
set_ti_thread_flag

arch/sparc/include/asm/mmu_context_64.h:159:4: error: implicit declaration of 
function 'clear_tsk_thread_flag'; did you mean 'clear_ti_thread_flag'? 
[-Werror=implicit-function-declaration]

clear_tsk_thread_flag(prev, TIF_MCDPER);
^
clear_ti_thread_flag
arch/sparc/include/asm/mmu_context_64.h: In function 
'finish_arch_post_lock_switch':

arch/sparc/include/asm/mmu_context_64.h:180:25: error: dereferencing pointer to 
incomplete type 'struct task_struct'

   if (current && current->mm && current->mm->context.adi) {
 ^~
In file included from arch/sparc/include/asm/processor.h:5:0,
 from arch/sparc/include/asm/spinlock_64.h:12,
 from arch/sparc/include/asm/spinlock.h:5,
 from include/linux/spinlock.h:88,
 from arch/sparc/include/asm/mmu_context_64.h:9,
 from arch/sparc/include/asm/mmu_context.h:5,
 from include/linux/mmu_context.h:5,
 from drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h:29,
 from drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c:23:

arch/sparc/include/asm/processor_64.h:194:28: error: implicit declaration of 
function 'task_thread_info'; did you mean 'test_thread_flag'? 
[-Werror=implicit-function-declaration]

 #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
^

arch/sparc/include/asm/mmu_context_64.h:183:11: note: in expansion of macro 
'task_pt_regs'

regs = task_pt_regs(current);
   ^~~~

arch/sparc/include/asm/processor_64.h:194:49: error: invalid type argument of 
'->' (have 'int')

 #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
 ^

arch/sparc/include/asm/mmu_context_64.h:183:11: note: in expansion of macro 
'task_pt_regs'

regs = task_pt_regs(current);
   ^~~~
In file included from include/linux/cred.h:21:0,
 from include/linux/seq_file.h:12,
 from include/linux/pinctrl/consumer.h:17,
 from include/linux/pinctrl/devinfo.h:21,
 from include/linux/device.h:23,
 from include/linux/cdev.h:8,
 from include/drm/drmP.h:36,
 from drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c:25:
include/linux/sched.h: At top level:

include/linux/sched.h:1530:20: warning: conflicting types for 
'set_tsk_thread_flag'

 static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag)
^~~

include/linux/sched.h:1530:20: error: static declaration of 
'set_tsk_thread_flag' follows non-static declaration

In file included from arch/sparc/include/asm/mmu_context.h:5:0,
 from include/linux/mmu_context.h:5,
 from drive

[PATCH v12 10/11] sparc64: Add support for ADI (Application Data Integrity)

2018-02-21 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
Reviewed-by: Anthony Yznaga <anthony.yzn...@oracle.com>
---
v10:
- Added code to return from kernel path to set PSTATE.mcde if
  kernel continues execution in another thread (Suggested by
  Anthony Yznaga)
v9:
- Added code to migrate ADI tags to copy_highpage() to
  ensure tags get copied on page migration
- Improved code to detect underflow and overflow when allocating
  tag storage
v8: 
- Added note to doc about non-faulting loads not triggering
  ADI tag mismatch and more details on special tag values
  of 0x0 and 0xf, as suggested by Anthony Yznaga)
- Added an IPI on mprotect(...PROT_ADI...) call to set
  TSTATE.MCDE on threads running on other processors and
  restore of TSTATE.MCDE on context switch (suggested by
  David Miller)
- Removed restriction on enabling ADI on read-only memory
  (suggested by Anthony Yznaga)
- Changed kzalloc() for tag storage to use GFP_NOWAIT
- Added code to handle overflow and underflow when allocating
  tag storage, as suggested by Anthony Yznaga
- Replaced sun_m7_patch_1insn_range() with sun4v_patch_1insn_range()
  which is functionally identical (suggested by Anthony Yznaga)
- Added membar after restoring ADI tags in copy_user_highpage(),
  as suggested by David Miller

v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 278 +
 arch/sparc/include/asm/mman.h   |  84 -
 arch/sparc/include/asm/mmu_64.h |  17 ++
 

[PATCH v12 00/11] Application Data Integrity feature introduced by SPARC M7

2018-02-21 Thread Khalid Aziz
ff 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//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 (11):
  signals, sparc: Add signal codes for ADI violations
  mm, swap: Add infrastructure for saving page metadata 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
  mm: Allow arch code to override copy_highpage()
  sparc64: Add support for ADI (Application Data Integrity)
  sparc64: Update signal delivery to use new helper functions

 Documentation/sparc/adi.txt | 278 ++
 arch/powerpc/include/asm/mman.h |   4 +-
 arch/powerpc/kernel/syscalls.c  |   2 +-
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  47 
 arch/sparc/include/asm/elf_64.h |   5 +
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  84 ++-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 
 arch/sparc/include/asm/page_64.h|   6 +
 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|  11 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/include/uapi/asm/pstate.h|  10 +
 arch/sparc/ke

Re: [PATCH v11 00/10] Application Data Integrity feature introduced by SPARC M7

2018-02-07 Thread Khalid Aziz

On 02/07/2018 12:38 AM, ebied...@xmission.com wrote:

Khalid Aziz <khalid.a...@oracle.com> writes:


On 02/01/2018 07:29 PM, ebied...@xmission.com wrote:

Khalid Aziz <khalid.a...@oracle.com> writes:


V11 changes:
This series is same as v10 and was simply rebased on 4.15 kernel. Can
mm maintainers please review patches 2, 7, 8 and 9 which are arch
independent, and include/linux/mm.h and mm/ksm.c changes in patch 10
and ack these if everything looks good?


I am a bit puzzled how this differs from the pkey's that other
architectures are implementing to achieve a similar result.

I am a bit mystified why you don't store the tag in a vma
instead of inventing a new way to store data on page out.


Hello Eric,

As Steven pointed out, sparc sets tags per cacheline unlike pkey. This results
in much finer granularity for tags that pkey and hence requires larger tag
storage than what we can do in a vma.


*Nod*   I am a bit mystified where you keep the information in memory.
I would think the tags would need to be stored per cacheline or per
tlb entry, in some kind of cache that could overflow.  So I would be
surprised if swapping is the only time this information needs stored
in memory.  Which makes me wonder if you have the proper data
structures.

I would think an array per vma or something in the page tables would
tend to make sense.

But perhaps I am missing something.


The ADI tags are stored in spare bits in the RAM. ADI tag storage is 
managed entirely by memory controller which maintains these tags per ADI 
block. An ADI block is the same size as cacheline on M7. Tags for each 
ADI block are associated with the physical ADI block, not the virtual 
address. When a physical page is reused, the physical ADI tag storage 
for that page is overwritten with new ADI tags, hence we need to store 
away the tags when we swap out a page. Kernel updates the ADI tags for 
physical page when it swaps a new page in. Each vma can cover variable 
number of pages so it is best to store a pointer to the tag storage in 
vma as opposed to actual tags in an array. Each 8K page can have 128 
tags on it. Since each tag is 4 bits, we need 64 bytes per page to store 
the tags. That can add up for a large vma.





Can you please use force_sig_fault to send these signals instead
of force_sig_info.  Emperically I have found that it is very
error prone to generate siginfo's by hand, especially on code
paths where several different si_codes may apply.  So it helps
to go through a helper function to ensure the fiddly bits are
all correct.  AKA the unused bits all need to be set to zero before
struct siginfo is copied to userspace.



What you say makes sense. I followed the same code as other fault handlers for
sparc. I could change just the fault handlers for ADI related faults. Would it
make more sense to change all the fault handlers in a separate patch and keep
the code in arch/sparc/kernel/traps_64.c consistent? Dave M, do you have a
preference?


It is my intention post -rc1 to start sending out patches to get the
rest of not just sparc but all of the architectures using the new
helpers.  I have the code I just ran out of time befor the merge
window opened to ensure everything had a good thorough review.

So if you can handle the your new changes I expect I will handle the
rest.



I can add a patch at the end of my series to update all force_sig_info() 
in my patchset to force_sig_fault(). That will sync my patches up with 
your changes cleanly. Does that work for you? I can send an updated 
series with this change. Can you review and ack the patches after this 
change.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v11 00/10] Application Data Integrity feature introduced by SPARC M7

2018-02-02 Thread Khalid Aziz

On 02/01/2018 07:29 PM, ebied...@xmission.com wrote:

Khalid Aziz <khalid.a...@oracle.com> writes:


V11 changes:
This series is same as v10 and was simply rebased on 4.15 kernel. Can
mm maintainers please review patches 2, 7, 8 and 9 which are arch
independent, and include/linux/mm.h and mm/ksm.c changes in patch 10
and ack these if everything looks good?


I am a bit puzzled how this differs from the pkey's that other
architectures are implementing to achieve a similar result.

I am a bit mystified why you don't store the tag in a vma
instead of inventing a new way to store data on page out.


Hello Eric,

As Steven pointed out, sparc sets tags per cacheline unlike pkey. This 
results in much finer granularity for tags that pkey and hence requires 
larger tag storage than what we can do in a vma.




Can you please use force_sig_fault to send these signals instead
of force_sig_info.  Emperically I have found that it is very
error prone to generate siginfo's by hand, especially on code
paths where several different si_codes may apply.  So it helps
to go through a helper function to ensure the fiddly bits are
all correct.  AKA the unused bits all need to be set to zero before
struct siginfo is copied to userspace.



What you say makes sense. I followed the same code as other fault 
handlers for sparc. I could change just the fault handlers for ADI 
related faults. Would it make more sense to change all the fault 
handlers in a separate patch and keep the code in 
arch/sparc/kernel/traps_64.c consistent? Dave M, do you have a preference?


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v11 10/10] sparc64: Add support for ADI (Application Data Integrity)

2018-02-01 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
Reviewed-by: Anthony Yznaga <anthony.yzn...@oracle.com>
---
v10:
- Added code to return from kernel path to set PSTATE.mcde if
  kernel continues execution in another thread (Suggested by
  Anthony Yznaga)
v9:
- Added code to migrate ADI tags to copy_highpage() to
  ensure tags get copied on page migration
- Improved code to detect underflow and overflow when allocating
  tag storage
v8: 
- Added note to doc about non-faulting loads not triggering
  ADI tag mismatch and more details on special tag values
  of 0x0 and 0xf, as suggested by Anthony Yznaga)
- Added an IPI on mprotect(...PROT_ADI...) call to set
  TSTATE.MCDE on threads running on other processors and
  restore of TSTATE.MCDE on context switch (suggested by
  David Miller)
- Removed restriction on enabling ADI on read-only memory
  (suggested by Anthony Yznaga)
- Changed kzalloc() for tag storage to use GFP_NOWAIT
- Added code to handle overflow and underflow when allocating
  tag storage, as suggested by Anthony Yznaga
- Replaced sun_m7_patch_1insn_range() with sun4v_patch_1insn_range()
  which is functionally identical (suggested by Anthony Yznaga)
- Added membar after restoring ADI tags in copy_user_highpage(),
  as suggested by David Miller

v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error
 Documentation/sparc/adi.txt | 278 +
 arch/sparc/include/asm/mman.h   |  84 -
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch

[PATCH v11 00/10] Application Data Integrity feature introduced by SPARC M7

2018-02-01 Thread Khalid Aziz
 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//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 (10):
  signals, sparc: Add signal codes for ADI violations
  mm, swap: Add infrastructure for saving page metadata 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
  mm: Allow arch code to override copy_highpage()
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 278 ++
 arch/powerpc/include/asm/mman.h |   4 +-
 arch/powerpc/kernel/syscalls.c  |   2 +-
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  47 
 arch/sparc/include/asm/elf_64.h |   5 +
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  84 ++-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 
 arch/sparc/include/asm/page_64.h|   6 +
 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|  11 +
 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  | 397 
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/etrap_64.S|  27 ++-
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   2 +
 arch/sparc/kernel/process_64.c  |  25 ++
 arch/sparc/kernel/rtrap_64.S|  33 ++-
 arch/sparc/kernel/setup_64.c|   2 +
 arch/sparc/kernel/sun4v_mcd.S  

[PATCH v10 00/10] Application Data Integrity feature introduced by SPARC M7

2017-11-15 Thread Khalid Aziz
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//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 (10):
  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
  mm: Allow arch code to override copy_highpage()
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 278 ++
 arch/powerpc/include/asm/mman.h |   4 +-
 arch/powerpc/kernel/syscalls.c  |   2 +-
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  47 
 arch/sparc/include/asm/elf_64.h |   9 +
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  84 ++-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 
 arch/sparc/include/asm/page_64.h|   6 +
 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|  11 +
 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  | 397 
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/etrap_64.S|  27 ++-
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   2 +
 arch/sparc/kernel/process_64.c  |  25 ++
 arch/sparc/kernel/rtrap_64.S|  33 ++-
 arch/sparc/kernel/setup_64.c|   2 +
 arch/sparc/kernel/sun4v_mcd.S   |  18 ++
 arch/sparc/kernel/traps_64.c| 142 +++-
 arch/sparc/kernel/ttable_64.S   |   6 +-
 arch/sparc/kernel/urtt_fill.S   |   7 +-
 arch/sparc/kernel/vmlinux.lds.S |   5 +
 arch/sparc/mm/gup.c |  37 +++
 arch/sparc/mm/hugetlbpage.c   

[PATCH v10 10/10] sparc64: Add support for ADI (Application Data Integrity)

2017-11-15 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v10:
- Added code to return from kernel path to set PSTATE.mcde if
  kernel continues execution in another thread (Suggested by
  Anthony Yznaga)
v9:
- Added code to migrate ADI tags to copy_highpage() to
  ensure tags get copied on page migration
- Improved code to detect underflow and overflow when allocating
  tag storage
v8: 
- Added note to doc about non-faulting loads not triggering
  ADI tag mismatch and more details on special tag values
  of 0x0 and 0xf, as suggested by Anthony Yznaga)
- Added an IPI on mprotect(...PROT_ADI...) call to set
  TSTATE.MCDE on threads running on other processors and
  restore of TSTATE.MCDE on context switch (suggested by
  David Miller)
- Removed restriction on enabling ADI on read-only memory
  (suggested by Anthony Yznaga)
- Changed kzalloc() for tag storage to use GFP_NOWAIT
- Added code to handle overflow and underflow when allocating
  tag storage, as suggested by Anthony Yznaga
- Replaced sun_m7_patch_1insn_range() with sun4v_patch_1insn_range()
  which is functionally identical (suggested by Anthony Yznaga)
- Added membar after restoring ADI tags in copy_user_highpage(),
  as suggested by David Miller

v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 278 +
 arch/sparc/include/asm/mman.h   |  84 -
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 ++
 arch/sparc

[PATCH v9 10/10] sparc64: Add support for ADI (Application Data Integrity)

2017-10-20 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v9:
- Added code to migrate ADI tags to copy_highpage() to
  ensure tags get copied on page migration
- Improved code to detect underflow and overflow when allocating
  tag storage
v8: 
- Added note to doc about non-faulting loads not triggering
  ADI tag mismatch and more details on special tag values
  of 0x0 and 0xf, as suggested by Anthony Yznaga)
- Added an IPI on mprotect(...PROT_ADI...) call to set
  TSTATE.MCDE on threads running on other processors and
  restore of TSTATE.MCDE on context switch (suggested by
  David Miller)
- Removed restriction on enabling ADI on read-only memory
  (suggested by Anthony Yznaga)
- Changed kzalloc() for tag storage to use GFP_NOWAIT
- Added code to handle overflow and underflow when allocating
  tag storage, as suggested by Anthony Yznaga
- Replaced sun_m7_patch_1insn_range() with sun4v_patch_1insn_range()
  which is functionally identical (suggested by Anthony Yznaga)
- Added membar after restoring ADI tags in copy_user_highpage(),
  as suggested by David Miller

v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 278 +
 arch/sparc/include/asm/mman.h   |  84 -
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 ++
 arch/sparc/include/asm/page_64.h|   6 +
 arch/sparc/include/asm/pgtable_64.h |  46 +
 arch/sparc/include/asm/thread_info_64.h |   2 +-
 arch/sparc/include/asm/

[PATCH v9 00/10] Application Data Integrity feature introduced by SPARC M7

2017-10-20 Thread Khalid Aziz
 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//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 (10):
  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
  mm: Allow arch code to override copy_highpage()
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 278 ++
 arch/powerpc/include/asm/mman.h |   4 +-
 arch/powerpc/kernel/syscalls.c  |   2 +-
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 
 arch/sparc/include/asm/elf_64.h |   9 +
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  84 ++-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 
 arch/sparc/include/asm/page_64.h|   6 +
 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|  11 +
 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  | 396 
 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|   2 +
 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 |  69 ++
 arch/sparc/mm/tsb.c |  21 ++
 arch/x86/kernel/signal_compat.c |   2 +-
 include/asm-generic/pgtable.h   |  36 +++
 include/linux/highmem.h |   4 +
 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   |  14 ++
 45 files changed, 1427 

Re: [PATCH v8 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-10-13 Thread Khalid Aziz

On 10/13/2017 08:14 AM, Khalid Aziz wrote:

On 10/12/2017 02:27 PM, Anthony Yznaga wrote:



On Oct 12, 2017, at 7:44 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:


On 10/06/2017 04:12 PM, Anthony Yznaga wrote:
On Sep 25, 2017, at 9:49 AM, Khalid Aziz <khalid.a...@oracle.com> 
wrote:


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

I still don't believe migration is properly supported.  Your
implementation is relying on a fault happening on a page while its
migration is in progress so that do_swap_page() will be called, but
I don't see how do_swap_page() will be called if a fault does not
happen until after the migration has completed.


User pages are on LRU list and for the mapped pages on LRU list, 
migrate_pages() ultimately calls try_to_unmap_one and makes a 
migration swap entry for the page being migrated. This forces a page 
fault upon access on the destination node and the page is swapped 
back in from swap cache. The fault is forced by the migration swap 
entry, rather than fault being an accidental event. If page fault 
happens on the destination node while migration is in progress, 
do_swap_page() waits until migration is done. Please take a look at 
the code in __unmap_and_move().


I looked at the code again, and I now believe ADI tags are never 
restored for migrated pages.  Here's why:




I will take a look at it again. I have run extensive tests migrating 
pages of a process across multiple NUMA nodes over and over again and 
ADI tags were never lost, so this does work. I won't rule out the 
possibility of having missed a code path where tags are not restored and 
I will look for it.


Anthony,

I just ran my migration test again which:

- malloc's 16 GB of memory
- Assigns a rotating ADI tag every 64 bytes to the malloc'd buffer
- Writes a pattern to the entire buffer
- Verifies the pattern it wrote using ADI tagged addresses.

While this test was running, I had a script migrate test program pages 
across two NUMA nodes every 30 seconds using migratepages command. I did 
not see an ADI tag mismatch over multiple runs of this test. This test 
shows migration is working.


Can you give me a test that shows the failure you think we should see 
and I will debug it.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-10-13 Thread Khalid Aziz

On 10/12/2017 02:27 PM, Anthony Yznaga wrote:



On Oct 12, 2017, at 7:44 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:


On 10/06/2017 04:12 PM, Anthony Yznaga wrote:

On Sep 25, 2017, at 9:49 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

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

I still don't believe migration is properly supported.  Your
implementation is relying on a fault happening on a page while its
migration is in progress so that do_swap_page() will be called, but
I don't see how do_swap_page() will be called if a fault does not
happen until after the migration has completed.


User pages are on LRU list and for the mapped pages on LRU list, 
migrate_pages() ultimately calls try_to_unmap_one and makes a migration swap 
entry for the page being migrated. This forces a page fault upon access on the 
destination node and the page is swapped back in from swap cache. The fault is 
forced by the migration swap entry, rather than fault being an accidental 
event. If page fault happens on the destination node while migration is in 
progress, do_swap_page() waits until migration is done. Please take a look at 
the code in __unmap_and_move().


I looked at the code again, and I now believe ADI tags are never restored for 
migrated pages.  Here's why:



I will take a look at it again. I have run extensive tests migrating 
pages of a process across multiple NUMA nodes over and over again and 
ADI tags were never lost, so this does work. I won't rule out the 
possibility of having missed a code path where tags are not restored and 
I will look for it.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-10-12 Thread Khalid Aziz

Hi Anthony,

Please quote only the relevant parts of the patch with comments. That 
makes it much easier to find the comments.


On 10/06/2017 04:12 PM, Anthony Yznaga wrote:



On Sep 25, 2017, at 9:49 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

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


I still don't believe migration is properly supported.  Your
implementation is relying on a fault happening on a page while its
migration is in progress so that do_swap_page() will be called, but
I don't see how do_swap_page() will be called if a fault does not
happen until after the migration has completed.


User pages are on LRU list and for the mapped pages on LRU list, 
migrate_pages() ultimately calls try_to_unmap_one and makes a migration 
swap entry for the page being migrated. This forces a page fault upon 
access on the destination node and the page is swapped back in from swap 
cache. The fault is forced by the migration swap entry, rather than 
fault being an accidental event. If page fault happens on the 
destination node while migration is in progress, do_swap_page() waits 
until migration is done. Please take a look at the code in 
__unmap_and_move().




+#define finish_arch_post_lock_switch   finish_arch_post_lock_switch
+static inline void finish_arch_post_lock_switch(void)
+{
+   /* Restore the state of MCDPER register for the new process
+* just switched to.
+*/
+   if (adi_capable()) {
+   register unsigned long tmp_mcdper;
+
+   tmp_mcdper = test_thread_flag(TIF_MCDPER);
+   __asm__ __volatile__(
+   "mov %0, %%g1\n\t"
+   ".word 0x9d81\n\t"/* wr %g0, %g1, %mcdper" 
*/
+   ".word 0xaf902001\n\t"/* wrpr %g0, 1, %pmcdper 
*/
+   :
+   : "ir" (tmp_mcdper)
+   : "g1");
+   if (current && current->mm && current->mm->context.adi) {
+   struct pt_regs *regs;
+
+   regs = task_pt_regs(current);
+   regs->tstate |= TSTATE_MCDE;



This works, but it costs additional cycles on every context switch to
keep setting TSTATE_MCDE.  PSTATE.mcde=1 only affects loads and stores
to memory mapped with TTE.mcd=1 so there is no impact if it is set and
no memory is mapped with TTE.mcd=1.  That is why I suggested just
setting TSTATE_MCDE once when a process thread is initialized.


This change was suggested by David Miller. I believe there is merit to 
that suggestion.



+   /* Tag storage has not been allocated for this vma and space
+* is available in tag storage descriptor. Since this page is
+* being swapped out, there is high probability subsequent pages
+* in the VMA will be swapped out as well. Allocate pages to
+* store tags for as many pages in this vma as possible but not
+* more than TAG_STORAGE_PAGES. Each byte in tag space holds
+* two ADI tags since each ADI tag is 4 bits. Each ADI tag
+* covers adi_blksize() worth of addresses. Check if the hole is
+* big enough to accommodate full address range for using
+* TAG_STORAGE_PAGES number of tag pages.
+*/
+   size = TAG_STORAGE_PAGES * PAGE_SIZE;
+   end_addr = addr + (size*2*adi_blksize()) - 1;
+   /* Check for overflow. If overflow occurs, allocate only one page */
+   if (end_addr < addr) {
+   size = PAGE_SIZE;
+   end_addr = addr + (size*2*adi_blksize()) - 1;


end_addr could still overflow even with size = PAGE_SIZE.
Maybe you could just set end_addr to (unsigned long)-1 and recalculate
the size based on that.


I agree at theoretical level. The number of VA bits is already limited 
by the max implemented VA bit in hardware plus with ADI in use, top 4 
bits are not available as well either, so there is lot of unused room at 
the upper end of VA and end_addr is not going to roll over. 
Nevertheless, I can fix this as well for completeness sake.






+   }
+   if (hole_end < end_addr) {
+   /* Available hole is too small on the upper end of
+* address. Can we expand the range towards the lower
+* address and maximize use of this slot?
+*/
+   unsigned long tmp_addr;
+
+   end_addr = hole_end - 1;
+   tmp_addr = end_addr - (size*2*adi_blksize()) + 1;
+   /* Check for underflow. If underflow occurs, allocate
+* only one page for storing ADI tags
+*/
+   if (tmp_addr > addr) 

[PATCH v8 0/9] Application Data Integrity feature introduced by SPARC M7

2017-09-25 Thread Khalid Aziz
ments 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//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 | 278 +++
 arch/powerpc/include/asm/mman.h |   4 +-
 arch/powerpc/kernel/syscalls.c  |   2 +-
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 
 arch/sparc/include/asm/elf_64.h |   9 +
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  84 ++-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 +
 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|  11 +
 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  | 384 
 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|   2 +
 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 |  34 +++
 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   |  14 ++
 44 files changed, 1374 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

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v8 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-09-25 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v8: 
- Added note to doc about non-faulting loads not triggering
  ADI tag mismatch and more details on special tag values
  of 0x0 and 0xf, as suggested by Anthony Yznaga)
- Added an IPI on mprotect(...PROT_ADI...) call to set
  TSTATE.MCDE on threads running on other processors and
  restore of TSTATE.MCDE on context switch (suggested by
  David Miller)
- Removed restriction on enabling ADI on read-only memory
  (suggested by Anthony Yznaga)
- Changed kzalloc() for tag storage to use GFP_NOWAIT
- Added code to handle overflow and underflow when allocating
  tag storage, as suggested by Anthony Yznaga
- Replaced sun_m7_patch_1insn_range() with sun4v_patch_1insn_range()
  which is functionally identical (suggested by Anthony Yznaga)
- Added membar after restoring ADI tags in copy_user_highpage(),
  as suggested by David Miller

v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 278 ++
 arch/sparc/include/asm/mman.h   |  84 +-
 arch/sparc/include/asm/mmu_64.h |  17 ++
 arch/sparc/include/asm/mmu_context_64.h |  50 ++
 arch/sparc/include/asm/page_64.h|   4 +
 arch/sparc/include/asm/pgtable_64.h |  46 +
 arch/sparc/include/asm/thread_info_64.h |   2 +-
 arch/sparc/include/asm/trap_block.h |   2 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/kernel/adi_64.c  | 289 
 arch/sparc/kernel/etrap_64.S|  28 +++-
 arch/

Re: [PATCH v7 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-09-06 Thread Khalid Aziz

On 09/04/2017 10:25 AM, Pavel Machek wrote:

Hi!


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.


I'm afraid I still don't understand what this is meant to prevent.

IOMMU ignores these, so this is not to prevent rogue DMA from doing
bad stuff.

Will gcc be able to compile code that uses these automatically? That
does not sound easy to me. Can libc automatically use this in malloc()
to prevent accessing freed data when buffers are overrun?

Is this for benefit of JITs?



David explained it well. Yes, preventing buffer overflow is one of the 
uses of ADI. Protecting critical data from wild writes caused by 
programming errors is another use. ADI can be used for debugging as well 
during development.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-08-31 Thread Khalid Aziz

On 08/30/2017 06:09 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 30 Aug 2017 17:23:37 -0600


That is an interesting idea. This would enable TSTATE_MCDE on all
threads of a process as soon as one thread enables it. If we consider
the case where the parent creates a shared memory area and spawns a
bunch of threads. These threads access the shared memory without ADI
enabled. Now one of the threads decides to enable ADI on the shared
memory. As soon as it does that, we enable TSTATE_MCDE across all
threads and since threads are all using the same TTE for the shared
memory, every thread becomes subject to ADI verification. If one of
the other threads was in the middle of accessing the shared memory, it
will get a sigsegv. If we did not enable TSTATE_MCDE across all
threads, it could have continued execution without fault. In other
words, updating TSTATE_MCDE across all threads will eliminate the
option of running some threads with ADI enabled and some not while
accessing the same shared memory. This could be necessary at least for
short periods of time before threads can communicate with each other
and all switch to accessing shared memory with ADI enabled using same
tag. Does that sound like a valid use case or am I off in the weeds
here?


A threaded application needs to synchronize and properly orchestrate
access to shared memory.

When a change is made to a mappping, in this case setting ADI
attributes, it's being done for the address space not the thread.

And the address space is shared amongst threads.

Therefore ADI is not really a per-thread property but rather
a per-address-space property.



That does make sense.

Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-08-30 Thread Khalid Aziz

On 08/30/2017 04:38 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 30 Aug 2017 16:27:54 -0600


+#define arch_calc_vm_prot_bits(prot, pkey)
sparc_calc_vm_prot_bits(prot)
+static inline unsigned long sparc_calc_vm_prot_bits(unsigned long
prot)
+{
+   if (prot & PROT_ADI) {
+   struct pt_regs *regs;
+
+   if (!current->mm->context.adi) {
+   regs = task_pt_regs(current);
+   regs->tstate |= TSTATE_MCDE;
+   current->mm->context.adi = true;

If a process is multi-threaded when it enables ADI on some memory for
the first time, TSTATE_MCDE will only be set for the calling thread
and it will not be possible to enable it for the other threads.
One possible way to handle this is to enable TSTATE_MCDE for all user
threads when they are initialized if adi_capable() returns true.



Or set TSTATE_MCDE unconditionally here by removing "if
(!current->mm->context.adi)"?


I think you have to make "ADI enabled" a property of the mm_struct.

Then you can broadcast to mm->cpu_vm_mask a per-cpu interrupt that
updates regs->tstate of a thread using 'mm' is currently executing.

And in the context switch code you set TSTATE_MCDE if it's not set
already.

That should cover all threaded case.


That is an interesting idea. This would enable TSTATE_MCDE on all 
threads of a process as soon as one thread enables it. If we consider 
the case where the parent creates a shared memory area and spawns a 
bunch of threads. These threads access the shared memory without ADI 
enabled. Now one of the threads decides to enable ADI on the shared 
memory. As soon as it does that, we enable TSTATE_MCDE across all 
threads and since threads are all using the same TTE for the shared 
memory, every thread becomes subject to ADI verification. If one of the 
other threads was in the middle of accessing the shared memory, it will 
get a sigsegv. If we did not enable TSTATE_MCDE across all threads, it 
could have continued execution without fault. In other words, updating 
TSTATE_MCDE across all threads will eliminate the option of running some 
threads with ADI enabled and some not while accessing the same shared 
memory. This could be necessary at least for short periods of time 
before threads can communicate with each other and all switch to 
accessing shared memory with ADI enabled using same tag. Does that sound 
like a valid use case or am I off in the weeds here?


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-08-16 Thread Khalid Aziz

On 08/15/2017 10:58 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed,  9 Aug 2017 15:26:02 -0600


+void adi_restore_tags(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, pte_t pte)
+{

  ...

+   tag = tag_start(addr, tag_desc);
+   paddr = pte_val(pte) & _PAGE_PADDR_4V;
+   for (tmp = paddr; tmp < (paddr+PAGE_SIZE); tmp += adi_blksize()) {
+   version1 = (*tag) >> 4;
+   version2 = (*tag) & 0x0f;
+   *tag++ = 0;
+   asm volatile("stxa %0, [%1] %2\n\t"
+   :
+   : "r" (version1), "r" (tmp),
+ "i" (ASI_MCD_REAL));
+   tmp += adi_blksize();
+   asm volatile("stxa %0, [%1] %2\n\t"
+   :
+   : "r" (version2), "r" (tmp),
+ "i" (ASI_MCD_REAL));
+   }
+   asm volatile("membar #Sync\n\t");


You do a membar here.


+   for (i = pfrom; i < (pfrom + PAGE_SIZE); i += adi_blksize()) {
+   asm volatile("ldxa [%1] %2, %0\n\t"
+   : "=r" (adi_tag)
+   :  "r" (i), "i" (ASI_MCD_REAL));
+   asm volatile("stxa %0, [%1] %2\n\t"
+   :
+   : "r" (adi_tag), "r" (pto),
+ "i" (ASI_MCD_REAL));


But not here.

Is this OK?  I suspect you need to add a membar this this second piece
of MCD tag storing code.


Hi Dave,

You are right. This tag storing code needs membar as well. I will add that.

Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 9/9] sparc64: Add support for ADI (Application Data Integrity)

2017-08-09 Thread Khalid Aziz
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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v7:
- 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
- Added code to copy ADI tags on COW
- Updated values for auxiliary vectors to not conflict with
  values on other architectures to avoid conflict in glibc. glibc
  consolidates all auxiliary vectors into its headers and
  duplicate values in consolidated header are problematic
- Disable same page merging on ADI enabled pages since ADI tags
  may not match on pages with identical data
- Broke the patch up further into smaller patches

v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 272 +++
 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 |  46 ++
 arch/sparc/include/asm/thread_info_64.h |   2 +-
 arch/sparc/include/asm/trap_block.h |   2 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/kernel/adi_64.c  | 277 
 arch/sparc/kernel/etrap_64.S|  28 +++-
 arch/sparc/kernel/process_64.c  |  25 +++
 arch/sparc/kernel/setup_64.c|  11 +-
 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 +++
 include/linux/mm.h  |   3 +
 mm/ksm.c|   4 +
 20 files changed, 913 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/sparc/adi.txt

diff --git a/Documentation/sparc/adi.txt b/Documentation/sparc/adi.txt
new file mode 100644
index ..383bc65fec1e
--- /dev/null
+++ b/Documentation/sparc/adi.txt
@@ -0,0 +1,272 @@
+Application Data Integrity (ADI)
+
+
+SPARC M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once AD

[PATCH v7 0/9] Application Data Integrity feature introduced by SPARC M7

2017-08-09 Thread Khalid Aziz
en 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

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-03-06 Thread Khalid Aziz

On 03/06/2017 05:13 PM, Anthony Yznaga wrote:



On Feb 28, 2017, at 10:35 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

diff --git a/arch/sparc/kernel/etrap_64.S b/arch/sparc/kernel/etrap_64.S
index 1276ca2..7be33bf 100644
--- a/arch/sparc/kernel/etrap_64.S
+++ b/arch/sparc/kernel/etrap_64.S
@@ -132,7 +132,33 @@ etrap_save:save%g2, -STACK_BIAS, %sp
stx %g6, [%sp + PTREGS_OFF + PT_V9_G6]
stx %g7, [%sp + PTREGS_OFF + PT_V9_G7]
or  %l7, %l0, %l7
-   sethi   %hi(TSTATE_TSO | TSTATE_PEF), %l0
+661:   sethi   %hi(TSTATE_TSO | TSTATE_PEF), %l0
+   /*
+* If userspace is using ADI, it could potentially pass
+* a pointer with version tag embedded in it. To maintain
+* the ADI security, we must enable PSTATE.mcde. Userspace
+* would have already set TTE.mcd in an earlier call to
+* kernel and set the version tag for the address being
+* dereferenced. Setting PSTATE.mcde would ensure any
+* access to userspace data through a system call honors
+* ADI and does not allow a rogue app to bypass ADI by
+* using system calls. Setting PSTATE.mcde only affects
+* accesses to virtual addresses that have TTE.mcd set.
+* Set PMCDPER to ensure any exceptions caused by ADI
+* version tag mismatch are exposed before system call
+* returns to userspace. Setting PMCDPER affects only
+* writes to virtual addresses that have TTE.mcd set and
+* have a version tag set as well.
+*/
+   .section .sun_m7_1insn_patch, "ax"
+   .word   661b
+   sethi   %hi(TSTATE_TSO | TSTATE_PEF | TSTATE_MCDE), %l0
+   .previous
+661:   nop
+   .section .sun_m7_1insn_patch, "ax"
+   .word   661b
+   .word 0xaf902001/* wrpr %g0, 1, %pmcdper */


Since PMCDPER is never cleared, setting it here is quickly going to set it on all CPUs 
and then become an expensive "nop" that burns ~50 cycles each time through 
etrap.  Consider setting it at boot time and when a CPU is DR'd into the system.

Anthony



I considered that possibility. What made me uncomfortable with that is 
there is no way to prevent a driver/module or future code elsewhere in 
kernel from clearing PMCDPER with possibly good reason. If that were to 
happen, setting PMCDPER here ensures kernel will always see consistent 
behavior with system calls. It does come at a cost. Is that cost 
unacceptable to ensure consistent behavior?


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 0/4] Application Data Integrity feature introduced by SPARC M7

2017-02-28 Thread Khalid Aziz
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 hour 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//numa_maps.


Outstanding issues:

- When sharing mmap'd ADI enabled areas with MAP_PRIVATE, copy-on-write
  results in a copy that does not have ADI enabled and ADI tags set.

- Two processes sharing a mmap's ADI enabled area with MAP_SHARED must
  coordinate setting of ADI tags or else one process can cause the other
  to get SIGSEGV.

I am working to solve these issues in subsequent patches. First issue
can be resolved by mapping the new COW pages with ADI enabled and copy
the ADI tags over to the new pages. This will increase the COW time
since tags must be copied over one cacheline at a time.

Second issue can possibly be solved by allowing only one task to mmap
with write permission when the memory pages are ADI enabled. All
subsequent mmap of this shared file would then be read-only mappings, or
mprotect() with PROT_ADI would be denied for subsequent mappings if
mapped pages have write permission. This would allow only one process to
change ADI tags but that process can still cause the processes that have
mmap'd read-only to crash if it changes ADI tags without coordinating
the change with other processes.

These ideas need to be explored more before implementing a fix. There
are potential race conditions as well in the solution for second issue
that will need to be evaluated and addressed.

---
Khalid Aziz (4):
  signals, sparc: Add signal codes for ADI violations
  mm: Add functions to support extra actions on swap in/out
  sparc64: Add support for ADI register fields, ASIs and traps
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 288 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   1 +
 arch/sparc/include/asm/mmu_context_64.h |  42 +
 arch/sparc/include/asm/pgtable_64.h |  87 +-
 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|   8 +
 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  |  93 +++
 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 +++
 a

[PATCH v6 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-02-28 Thread Khalid Aziz
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. It also adds handlers for
traps related to MCD. 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.

This initial implementation supports saving and restoring one tag per
page. A page must use same version tag across the entire page for the
tag to survive swap and migration. Swap swupport infrastructure in this
patch allows for this capability to be expanded to store/restore more
than one tag per page in future.

Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v6:
- 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. PSTATE.mcde and PMCDPER are set upon entry into
  kernel when running on an M7 processor. PSTATE.mcde being
  set only affects memory accesses that have TTE.mcd set.
  PMCDPER being set only affects writes to memory addresses
  that have TTE.mcd set. This ensures any faults caused by
  ADI tag mismatch on a write are exposed before kernel returns
  to userspace.

v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 292 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   1 +
 arch/sparc/include/asm/mmu_context_64.h |  42 +
 arch/sparc/include/asm/pgtable_64.h |  85 +-
 arch/sparc/include/asm/thread_info_64.h |   2 +-
 arch/sparc/include/asm/trap_block.h |   2 +
 arch/sparc/include/uapi/asm/auxvec.h|   8 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/kernel/Makefile  |   1 +
 arch/sparc/kernel/adi_64.c  |  93 ++
 arch/sparc/kernel/etrap_64.S|  28 ++-
 arch/sparc/kernel/mdesc.c   |   2 +
 arch/sparc/kernel/process_64.c  |  25 +++
 arch/sparc/kernel/setup_64.c|  11 +-
 arch/sparc/kernel/traps_64.c|  83 -
 arch/sparc/kernel/vmlinux.lds.S |   5 +
 arch/sparc/mm/gup.c |  37 
 include/linux/mm.h  |   2 +
 23 files changed, 825 insertions(+), 9 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

diff --git a/Documentation/sparc/adi.txt b/Documentation/sparc/adi.txt
new file mode 100644
index 000..93fb97e
--- /dev/null
+++ b/Documentation/sparc/adi.txt
@@ -0,0 +1,292 @@
+Application Data Integrity (ADI)
+
+
+SPARC M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once ADI is enabled and version tags are set for ranges of
+address space of a task, the processor will compare the tag in pointer

Re: [PATCH v5 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-31 Thread Khalid Aziz

On 01/30/2017 03:15 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 25 Jan 2017 12:57:16 -0700


+static inline void enable_adi(void)
+{

 ...

+   __asm__ __volatile__(
+   "rdpr %%pstate, %%g1\n\t"
+   "or %%g1, %0, %%g1\n\t"
+   "wrpr %%g1, %%g0, %%pstate\n\t"
+   ".word 0x83438000\n\t"/* rd %mcdper, %g1 */
+   ".word 0xaf91\n\t"/* wrpr  %g0, %g1, %pmcdper */
+   :
+   : "i" (PSTATE_MCDE)
+   : "g1");
+}


This is _crazy_ expensive.

This is 4 privileged register operations, every single one incurs a full
pipline flush and virtual cpu thread yield.

And we do this around _every_ single userspace access from the kernel
when the thread has ADI enabled.


Hi Dave,

Thanks for the feedback. This is very helpful. I checked and it indeed 
can cost 50+ cycles even on M7 processor for PSTATE accesses.




I think if the kernel manages the ADI metadata properly, you can get rid
of all of this.

On etrap, you change ESTATE_PSTATE{1,2} to have the MCDE bit enabled.
Then the kernel always runs with ADI enabled.


Running the kernel with PSTATE.mcde=1 can possibly be problematic as we 
had discussed earlier in this thread where keeping PSTATE.mcde enabled 
might mean kernel having to keep track of which pages still have tags 
set on them or flush tags on every page on free. I will go through the 
code again to see if it PSTATE.mcde can be turned on in kernel all the 
time, which might be the case if we can ensure kernel accesses pages 
with TTE.mcd cleared.




Furthermore, since the %mcdper register should be set to whatever the
current task has asked for, you should be able to avoid touching it
as well assuming that traps do not change %mcdper's value.


When running in privileged mode, it is the value of %pmcdper that 
matter, not %mcdper, hence I added code to sync %pmcdper with %mcdper 
when entering privileged mode. Nevertheless, one of the HW designers has 
suggested I might be able to get away without having to futz with 
%pmcdper by using membar before exiting privileged mode which might 
still get me the same effect I am looking for without the cost.


--
Khalid



Then you don't need to do anything special during userspace accesses
which seems to be the way this was designed to be used.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-25 Thread Khalid Aziz

On 01/25/2017 03:50 PM, Rob Gardner wrote:

On 01/25/2017 03:20 PM, Khalid Aziz wrote:

On 01/25/2017 03:00 PM, Rob Gardner wrote:

On 01/25/2017 12:57 PM, Khalid Aziz wrote:


@@ -157,6 +158,24 @@ int __get_user_pages_fast(unsigned long start,
int nr_pages, int write,
  pgd_t *pgdp;
  int nr = 0;
  +#ifdef CONFIG_SPARC64
+if (adi_capable()) {
+long addr = start;
+
+/* If userspace has passed a versioned address, kernel
+ * will not find it in the VMAs since it does not store
+ * the version tags in the list of VMAs. Storing version
+ * tags in list of VMAs is impractical since they can be
+ * changed any time from userspace without dropping into
+ * kernel. Any address search in VMAs will be done with
+ * non-versioned addresses. Ensure the ADI version bits
+ * are dropped here by sign extending the last bit before
+ * ADI bits. IOMMU does not implement version tags.
+ */
+addr = (addr << (long)adi_nbits()) >> (long)adi_nbits();



So you are depending on the sign extension to clear the ADI bits... but
this only happens if there is a zero in that "last bit before ADI bits".
If the last bit is a 1, then the ADI bits will be set instead of
cleared.  That seems like an unintended consequence given the comment. I
am aware of the value of adi_nbits() and of the number of valid bits in
a virtual address on the M7 processor, but wouldn't using 'unsigned
long' for everything here guarantee the ADI bits get cleared regardless
of the state of the last non-adi bit?


Sign extension is the right thing to do. MMU considers values of 0 and
15 for bits 63-60 to be untagged addresses and expects bit 59 to be
sign-extended for untagged virtual addresses. The code I added is
explicitly meant to sign-extend, not zero out the top 4 bits.


OK, that wasn't perfectly clear from the comment, which said "version
bits are dropped".

So sign extending will produce an address that the MMU can use, but will
it produce an address that will allow a successful search in the page
tables? ie, was this same sign extending done when first handing out
that virtual address to the user?



Yes to both your questions. When virtual addresses are handed out, the 
last implemented virtual address bit is sign-extended. Sign-extending 
when dropping version bits preserves that original sign-extension. This 
is why MMU considers tag values of 0 as well as 15 to be invalid because 
they both represent sign-extension of the last implemented virtual address.


--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-25 Thread Khalid Aziz

On 01/25/2017 03:00 PM, Rob Gardner wrote:

On 01/25/2017 12:57 PM, Khalid Aziz wrote:


@@ -157,6 +158,24 @@ int __get_user_pages_fast(unsigned long start,
int nr_pages, int write,
  pgd_t *pgdp;
  int nr = 0;
  +#ifdef CONFIG_SPARC64
+if (adi_capable()) {
+long addr = start;
+
+/* If userspace has passed a versioned address, kernel
+ * will not find it in the VMAs since it does not store
+ * the version tags in the list of VMAs. Storing version
+ * tags in list of VMAs is impractical since they can be
+ * changed any time from userspace without dropping into
+ * kernel. Any address search in VMAs will be done with
+ * non-versioned addresses. Ensure the ADI version bits
+ * are dropped here by sign extending the last bit before
+ * ADI bits. IOMMU does not implement version tags.
+ */
+addr = (addr << (long)adi_nbits()) >> (long)adi_nbits();



So you are depending on the sign extension to clear the ADI bits... but
this only happens if there is a zero in that "last bit before ADI bits".
If the last bit is a 1, then the ADI bits will be set instead of
cleared.  That seems like an unintended consequence given the comment. I
am aware of the value of adi_nbits() and of the number of valid bits in
a virtual address on the M7 processor, but wouldn't using 'unsigned
long' for everything here guarantee the ADI bits get cleared regardless
of the state of the last non-adi bit?


Sign extension is the right thing to do. MMU considers values of 0 and 
15 for bits 63-60 to be untagged addresses and expects bit 59 to be 
sign-extended for untagged virtual addresses. The code I added is 
explicitly meant to sign-extend, not zero out the top 4 bits.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-25 Thread Khalid Aziz
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 hour 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//numa_maps.


Outstanding issues:

- When sharing mmap'd ADI enabled areas with MAP_PRIVATE, copy-on-write
  results in a copy that does not have ADI enabled and ADI tags set.

- Two processes sharing a mmap's ADI enabled area with MAP_SHARED must
  coordinate setting of ADI tags or else one process can cause the other
  to get SIGSEGV.

I am working to solve these issues in subsequent patches. First issue
can be resolved by mapping the new COW pages with ADI enabled and copy
the ADI tags over to the new pages. This will increase the COW time
since tags must be copied over one cacheline at a time.

Second issue can possibly be solved by allowing only one task to mmap
with write permission when the memory pages are ADI enabled. All
subsequent mmap of this shared file would then be read-only mappings, or
mprotect() with PROT_ADI would be denied for subsequent mappings if
mapped pages have write permission. This would allow only one process to
change ADI tags but that process can still cause the processes that have
mmap'd read-only to crash if it changes ADI tags without coordinating
the change with other processes.

These ideas need to be explored more before implementing a fix. There
are potential race conditions as well in the solution for second issue
that will need to be evaluated and addressed.

---
Khalid Aziz (4):
  signals, sparc: Add signal codes for ADI violations
  mm: Add functions to support extra actions on swap in/out
  sparc64: Add support for ADI register fields, ASIs and traps
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 288 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   1 +
 arch/sparc/include/asm/mmu_context_64.h |  43 +
 arch/sparc/include/asm/pgtable_64.h |  87 +-
 arch/sparc/include/asm/thread_info_64.h |   1 +
 arch/sparc/include/asm/ttable.h |  10 ++
 arch/sparc/include/asm/uaccess_64.h | 120 -
 arch/sparc/include/uapi/asm/asi.h   |   5 +
 arch/sparc/include/uapi/asm/auxvec.h|   8 +
 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  |  93 +++
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   2 +
 arch/sparc/kernel/process_64.c  |  25 +++
 arch/sparc/kernel/sun4v_mcd.S   |  16 ++
 arch/sparc/kernel/traps_64.c| 142 +++-
 arch/sparc/kernel/ttable_64.S   |   6 +-
 arch/sparc/mm/gup.c |  37 
 arch/x86/kernel/signal_compat.c |   2 +-
 include/asm-generic/pgtable.h   |  16 ++
 include/linux/mm.h  |   2 +
 include/uapi/asm-generic/siginfo.h  |   5 +-
 mm/memor

[PATCH v5 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-25 Thread Khalid Aziz
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. It also adds handlers for
traps related to MCD. 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.

This initial implementation supports saving and restoring one tag per
page. A page must use same version tag across the entire page for the
tag to survive swap and migration. Swap swupport infrastructure in this
patch allows for this capability to be expanded to store/restore more
than one tag per page in future.

Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v5:
- 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

v4:
- Broke patch up into smaller patches

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

v2:
- Fixed a build error

 Documentation/sparc/adi.txt | 288 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   1 +
 arch/sparc/include/asm/mmu_context_64.h |  43 +
 arch/sparc/include/asm/pgtable_64.h |  85 +-
 arch/sparc/include/asm/thread_info_64.h |   1 +
 arch/sparc/include/asm/uaccess_64.h | 120 -
 arch/sparc/include/uapi/asm/auxvec.h|   8 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/kernel/Makefile  |   1 +
 arch/sparc/kernel/adi_64.c  |  93 +++
 arch/sparc/kernel/mdesc.c   |   2 +
 arch/sparc/kernel/process_64.c  |  25 +++
 arch/sparc/kernel/traps_64.c|  88 +-
 arch/sparc/mm/gup.c |  37 
 include/linux/mm.h  |   2 +
 20 files changed, 897 insertions(+), 12 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

diff --git a/Documentation/sparc/adi.txt b/Documentation/sparc/adi.txt
new file mode 100644
index 000..1740f8a
--- /dev/null
+++ b/Documentation/sparc/adi.txt
@@ -0,0 +1,288 @@
+Application Data Integrity (ADI)
+
+
+SPARC M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once ADI is enabled and version tags are set for ranges of
+address space of a task, the processor will compare the tag in pointers
+to memory in these ranges to the version set by the application
+previously. Access to memory is granted only if the tag in given
+pointer matches the tag set by the application. In case of mismatch,
+processor raises an exception.
+
+Following steps must be taken by a task to enable ADI fully:
+
+1. Set the user mode PSTATE.mcde bit. This acts as master switch for
+   the task's entire address space to enable/disable ADI for the task.
+
+2. Set TTE.mcd bit on any TLB entries that correspond to the range of
+   addresses ADI is being enabled on. MMU checks the version tag only
+   on the pages that have TTE.mcd bit set.
+
+3. Set the version tag for virtual addresses using stxa instruction
+   and one of the MCD specific ASIs. Each stxa instruction sets the
+

Re: [PATCH v4 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-17 Thread Khalid Aziz

On 01/16/2017 09:39 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 11 Jan 2017 09:12:54 -0700


diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 8a6982d..68b03bf 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 

 /* Unlike the OBP device tree, the machine description is a full-on
  * DAG.  An arbitrary number of ARCs are possible from one
@@ -1104,5 +1105,8 @@ void __init sun4v_mdesc_init(void)

cur_mdesc = hp;

+#ifdef CONFIG_SPARC64


mdesc.c is only built on sparc64, this ifdef is superfluous.


Good point. I will fix it.




+/* Update the state of MCDPER register in current task's mm context before
+ * dup so the dup'd task will inherit flags in this register correctly.
+ * Current task may have updated flags since it started running.
+ */
+int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+{
+   if (adi_capable() && src->mm) {
+   register unsigned long tmp_mcdper;
+
+   __asm__ __volatile__(
+   ".word 0x83438000\n\t"/* rd %mcdper, %g1 */
+   "mov %%g1, %0\n\t"
+   : "=r" (tmp_mcdper)
+   :
+   : "g1");
+   src->mm->context.mcdper = tmp_mcdper;


I don't like the idea of duplicating 'mm' state using the task struct
copy.  Why do not the MM handling interfaces handle this properly?

Maybe it means you've abstracted the ADI register handling in the
wrong place.  Maybe it's a thread property which is "pushed" from
the MM context.


I see what you are saying. This code updates mm->context.mcdper for the 
source thread with the current state of MCDPER since MCDPER can be 
changed by a userspace process any time. When userspace changes MCDPER, 
it is not saved into mm->context.mcdper until a context switch happens. 
This means during the timeslice for a thread, its mm->context.mcdper may 
not reflect the current value of MCDPER. Updating it ensures dup_mm() 
will copy the real current value of MCDPER into the newly forked thread. 
arch_dup_mmap() looks like a more appropriate place to do this. Do you 
agree?


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-17 Thread Khalid Aziz

On 01/16/2017 09:47 PM, David Miller wrote:

From: Dave Hansen 
Date: Wed, 11 Jan 2017 10:13:54 -0800


For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


Whoever allocates the memory (does the mmap()+mprotect() or whatever),
decides on the tag.  They set it, and this determines which virtual
address is valid to access that mapping.

It's like kmalloc() returns pointers with some weird bits set in the
upper bits of the address.  Behind the scenes kmalloc() sets the
TAG bits appropriately.

It doesn't, in that sense, matter where in the non-tagged virtual
address space the memory is mapped.  All that matters is that, for
a given page, the TAG bits in the virtual address used for loads
and stores to that mapping are set properly.

I think the fundamental thing being missed is that the TAG bits in the
virtual address are not interpreted by the TLB.  They are chopped off
before virtual address translation occurs.

The TAG bits of the virtual address serve only to indicate what ADI
value the load or store thinks is valid to use for access to that
piece of memory.

Or something like that... :-)


Hi David,

Your explanation is spot on. MMU looks at the tag bits only to determine 
if the process has permission to access the memory address. Tag bits are 
not part of VA->PA translation. The tags are stored in physical memory 
though and MMU compares the tag stored at physical address obtained from 
TLB translation to the tag embedded in VA. What that means is if two 
processes map the same physical page in their address space, they both 
must embed the same tag in the VA they present to MMU irrespective of 
where in each process' address space the page is mapped in. If one 
process changes the tag, stored in physical memory, the other process 
must also embed the new tag in its VA when accessing this shared mapped 
page. This is something to consider because a tag can be set and changed 
entirely from userspace with no kernel involvement as long as the 
process has write access to memory.


--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-17 Thread Khalid Aziz

On 01/17/2017 12:42 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Tue, 17 Jan 2017 12:32:46 -0700


On 01/16/2017 09:39 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 11 Jan 2017 09:12:54 -0700


+   __asm__ __volatile__(
+   ".word 0xa1438000\n\t"/* rd  %mcdper, %l0 */


Just use "rd %%asr14, %0" this way you don't have to play all of these
fixed register games which kill the code generated by gcc.  If you
forcefully clobber a windowed register like %l0 it means the function
being emitted can never be a leaf function, tail calls are no longer
allowed, etc.


Hi David,

"rd %%asr14, %0" should work but does not due to bugs in assembler -
<https://sourceware.org/ml/binutils/2016-03/msg00302.html>, and
<https://sourceware.org/ml/binutils/2016-03/msg00303.html>. These bugs
were fixed in binutils 2.27 but older assemblers will cause kernel
build to fail. Using byte coded equivalent is the safest option.


Fair enough.

Then please at least use %g1 or another usable global register to
avoid at least some of the problems I mentioned.



Sure, I will do that. Thanks for the review and feedback.

--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-17 Thread Khalid Aziz

On 01/16/2017 09:39 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed, 11 Jan 2017 09:12:54 -0700


+   __asm__ __volatile__(
+   ".word 0xa1438000\n\t"/* rd  %mcdper, %l0 */


Just use "rd %%asr14, %0" this way you don't have to play all of these
fixed register games which kill the code generated by gcc.  If you
forcefully clobber a windowed register like %l0 it means the function
being emitted can never be a leaf function, tail calls are no longer
allowed, etc.


Hi David,

"rd %%asr14, %0" should work but does not due to bugs in assembler - 
<https://sourceware.org/ml/binutils/2016-03/msg00302.html>, and 
<https://sourceware.org/ml/binutils/2016-03/msg00303.html>. These bugs 
were fixed in binutils 2.27 but older assemblers will cause kernel build 
to fail. Using byte coded equivalent is the safest option.





+   ".word 0x9d800011\n\t"/* wr  %g0, %l1, %mcdper 
*/


Likewise use "wr %%g0, %0, %%asr14"


+   ".word 0xaf91\n\t"/* wrpr  %g0, %g1, %pmcdper */


Hmmm, which %asr encodes %pmcdper?


%pmcdper is not an asr, rather a privileged register (pr23).

Thanks,
Khalid




diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 8a6982d..68b03bf 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 

 /* Unlike the OBP device tree, the machine description is a full-on
  * DAG.  An arbitrary number of ARCs are possible from one
@@ -1104,5 +1105,8 @@ void __init sun4v_mdesc_init(void)

cur_mdesc = hp;

+#ifdef CONFIG_SPARC64


mdesc.c is only built on sparc64, this ifdef is superfluous.


+/* Update the state of MCDPER register in current task's mm context before
+ * dup so the dup'd task will inherit flags in this register correctly.
+ * Current task may have updated flags since it started running.
+ */
+int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+{
+   if (adi_capable() && src->mm) {
+   register unsigned long tmp_mcdper;
+
+   __asm__ __volatile__(
+   ".word 0x83438000\n\t"/* rd %mcdper, %g1 */
+   "mov %%g1, %0\n\t"
+   : "=r" (tmp_mcdper)
+   :
+   : "g1");
+   src->mm->context.mcdper = tmp_mcdper;


I don't like the idea of duplicating 'mm' state using the task struct
copy.  Why do not the MM handling interfaces handle this properly?

Maybe it means you've abstracted the ADI register handling in the
wrong place.  Maybe it's a thread property which is "pushed" from
the MM context.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Khalid Aziz

On 01/13/2017 08:29 AM, Rob Gardner wrote:

On 01/13/2017 07:48 AM, Khalid Aziz wrote:

On 01/12/2017 06:31 PM, Rob Gardner wrote:

On 01/12/2017 05:22 PM, Khalid Aziz wrote:

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must
stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them
must use the same tag to access the shared memory, but if a process
accesses a shared page with TTE.mcde bit cleared, access will be
granted.




COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller.
The
requirement is every one sharing the page must switch to the new
tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again. Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to
protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I don't think you can write a tag to memory if you don't have write
access in the TTE. Writing a tag requires a store instruction, and if
the machine is at all sane, this will fault if you don't have write
access.



But could you have mmap'd the file writable, set the tags and then
changed the protection on memory to read-only? That would be the
logical way to ADI protect a memory being used to mmap a file. Right?



Sure, if you have write access to begin with, you can set memory
versions, then remove write access to the page. But I think the point is
that if a process doesn't have write access, and cannot get it, then it
will not ever be able to change memory versions. So in the example of a
non-root process opening /etc/passwd (read only), and mmaping it, the
mapping would be read-only as well. Personally I don't really see a use
case for ADI on memory mapped to a file. In an abstract sense, the
"backing store" for a memory mapped file is the file itself on disk, not
physical memory. And there is already a way to restrict access to files,
so perhaps ADI should simply be disallowed for memory mapped to files,
and this particular complication can be avoided. Thoughts?


Hi Rob,

That is a good way to look at it. Memory mapped files already have a 
protection mechanism in place.




Incidentally, I see ADI as primarily a way to protect memory from
improper access within a process or group of cooperating processes.
There is already a way to protect memory from unrelated processes, and
if that is circumvented somehow, then ADI won't help at all. Perhaps we
should stop talking about ADI as a "security" feature; It does add a
layer of protection against buffer overflow attacks, but this attack
only exists when there is a bug in the underlying application. If an
attacker gains access to the virtual memory for a process, then nothing
can help you.



That does make sense. Looking at ADI as a mechanism to prevent 
unintended improper access to memory through buffer overflow or other 
mechanism, would it still make sense to support ADI tags on mmap'd files 
within the group of cooperating processes? Say we have a process that 
mmap's a large file and then forks off a bunch of children that process 
smaller segments of that file. We would want to make sure these children 
do not step over each other's segments of the file due to programming 
flaw or compromise. Parent process could tag each segment with a 
different tag and give one tag to each child process.


I want to be sure we are not shutting down potential useful applications 
of ADI before we choose to not support ADI with memory mapped files.


I appreciate your input.

Thanks,
Khalid



Rob




--
Khalid


Rob





I understand your quetion better now. That is a very valid concern.
Using ADI tags to prevent an unauthorized process from just reading
data in memory, say an in-memory copy of database, is one of the use
cases

Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-13 Thread Khalid Aziz

On 01/12/2017 06:31 PM, Rob Gardner wrote:

On 01/12/2017 05:22 PM, Khalid Aziz wrote:

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them
must use the same tag to access the shared memory, but if a process
accesses a shared page with TTE.mcde bit cleared, access will be granted.




COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller. The
requirement is every one sharing the page must switch to the new tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again. Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I don't think you can write a tag to memory if you don't have write
access in the TTE. Writing a tag requires a store instruction, and if
the machine is at all sane, this will fault if you don't have write access.



But could you have mmap'd the file writable, set the tags and then 
changed the protection on memory to read-only? That would be the logical 
way to ADI protect a memory being used to mmap a file. Right?


--
Khalid


Rob





I understand your quetion better now. That is a very valid concern.
Using ADI tags to prevent an unauthorized process from just reading
data in memory, say an in-memory copy of database, is one of the use
cases for ADI. This means there is a reasonable case to allow enabling
ADI and setting tags even on non-writable mappings. On the other hand,
if an unauthorized process manages to map the right memory pages in
its address space, it can read them any way by not setting TTE.mcd.

Userspace app can set tag on any memory it has mapped in without
requiring assistance from kernel. Can this problem be solved by not
allowing setting TTE.mcd on non-writable mappings? Doesn't the same
problem occur on writable mappings? If a privileged process mmap()'s a
writable file with MAP_SHARED, enables ADI and sets tag on the mmap'd
memory region, then another lower privilege process mmap's the same
file writable (assuming file permissions allow it to), enables ADI and
sets a different tag on it, the privileged process would get SIGSEGV
when it tries to access the mmap'd file. Right?




--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-12 Thread Khalid Aziz

On 01/12/2017 10:53 AM, Dave Hansen wrote:

On 01/12/2017 08:50 AM, Khalid Aziz wrote:

2. Any shared page that has ADI protection enabled on it, must stay ADI
protected across all processes sharing it.


Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?


ADI protection applies across all processes in terms of all of them must 
use the same tag to access the shared memory, but if a process accesses 
a shared page with TTE.mcde bit cleared, access will be granted.





COW creates an intersection of the two. It creates a new copy of the
shared data. It is a new data page and hence the process creating it
must be the one responsible for enabling ADI protection on it.


Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?


It is also a copy of what was ADI protected data, so should it
inherit the protection instead?


I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.


I misspoke earlier. I had misinterpreted the results of test I ran.
Changing the tag on shared memory is allowed by memory controller. The
requirement is every one sharing the page must switch to the new tag or
else they get SIGSEGV.


I asked this in the last mail, but I guess I'll ask it again.  Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?


I understand your quetion better now. That is a very valid concern. 
Using ADI tags to prevent an unauthorized process from just reading data 
in memory, say an in-memory copy of database, is one of the use cases 
for ADI. This means there is a reasonable case to allow enabling ADI and 
setting tags even on non-writable mappings. On the other hand, if an 
unauthorized process manages to map the right memory pages in its 
address space, it can read them any way by not setting TTE.mcd.


Userspace app can set tag on any memory it has mapped in without 
requiring assistance from kernel. Can this problem be solved by not 
allowing setting TTE.mcd on non-writable mappings? Doesn't the same 
problem occur on writable mappings? If a privileged process mmap()'s a 
writable file with MAP_SHARED, enables ADI and sets tag on the mmap'd 
memory region, then another lower privilege process mmap's the same file 
writable (assuming file permissions allow it to), enables ADI and sets a 
different tag on it, the privileged process would get SIGSEGV when it 
tries to access the mmap'd file. Right?


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz

On 01/11/2017 12:11 PM, Dave Hansen wrote:

On 01/11/2017 10:50 AM, Khalid Aziz wrote:

On 01/11/2017 11:13 AM, Dave Hansen wrote:

On 01/11/2017 08:56 AM, Khalid Aziz wrote:
For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


The two processes have to agree on the tag. This is part of the security
design to prevent other processes from accessing pages belonging to
another process unless they know the tag set on those pages.


So what do you do with static data, say from a shared executable?  You
need to ensure that two different processes from two different privilege
domains can't set different tags on the same physical memory.  That
would seem to mean that you must not allow tags to be set of memory
unless you have write access to it.  Or, you have to ensure that any
file that you might want to use this feature on is entirely unreadable
(well, un-mmap()-able really) by anybody that you are not coordinating with.


All of the tag coordination can happen in userspace. Once a process sets 
a tag on a physical page mapped in its address space, another process 
that has mapped the same physical page in its address space can only set 
the tag to exact same value. Attempts to set a different tag are caught 
by memory controller and result in MCD trap and kernel sends SIGSEGV to 
the process trying to set a different tag.




If you want to use it on copy-on-write'able data, you've got to ensure
that you've got entirely private copies.  I'm not sure we even have an
interface to guarantee that.  How could this work after a fork() on
un-COW'd, but COW'able data?


On COW, kernel maps the the source and destination pages with 
kmap_atomic() and copies the data over to the new page and the new page 
wouldn't be ADI protected unless the child process chooses to do so. 
This wouldn't change with ADI as far as private copies are concerned. 
Please do correct me if I get something wrong here. Quick tests with COW 
data show everything working as expected but your asking about COW has 
raised a few questions in my own mind. I am researching through docs and 
running experiments to validate my thinking and I will give you more 
definite information on whether COW would mess ADI up.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz

On 01/11/2017 11:13 AM, Dave Hansen wrote:

On 01/11/2017 08:56 AM, Khalid Aziz wrote:

On 01/11/2017 09:33 AM, Dave Hansen wrote:

On 01/11/2017 08:12 AM, Khalid Aziz wrote:

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.


Is there a cost in the hardware associated with doing this "ADI
checking"?  For instance, instead of having this new mprotect()
interface, why not just always set TTE.mcd on all PTEs?


There is no performance penalty in the MMU to check tags, but if
PSTATE.mcd bit is set and TTE.mcde is set, the tag in VA must match what
was set on the physical page for all memory accesses.


OK, then I'm misunderstanding the architecture again.

For memory shared by two different processes, do they have to agree on
what the tags are, or can they differ?


The two processes have to agree on the tag. This is part of the security 
design to prevent other processes from accessing pages belonging to 
another process unless they know the tag set on those pages.





Potential for side
effects is too high in such case and would require kernel to either
track tags for every page as they are re-allocated or migrated, or scrub
pages constantly to ensure we do not get spurious tag mismatches. Unless
there is a very strong reason to blindly set TTE.mcd on every PTE, I
think the risk of instability is too high without lot of extra code.


Ahh, ok.  That makes sense.  Clearing the tags is expensive.  We must
either clear tags or know the previous tags of the memory before we
access it.

Are any of the tags special?  Do any of them mean "don't do any
checking", or similar?



Tag values of 0 and 15 can be considered special. Setting tag to 15 on 
memory range is disallowed. Accessing a memory location whose tag is 
cleared (means set to 0) with any tag value in the VA is allowed. Once a 
tag is set on a memory, and PSTATE.mcde and TTE.mcd are set, there isn't 
a tag that can be used to bypass version check by MMU.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 4/4] sparc64: Add support for ADI (Application Data Integrity)

2017-01-11 Thread Khalid Aziz
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. It also adds handlers for
traps related to MCD. 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.

This initial implementation supports saving and restoring one tag per
page. A page must use same version tag across the entire page for the
tag to survive swap and migration. Swap swupport infrastructure in this
patch allows for this capability to be expanded to store/restore more
than one tag per page in future.

Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v2:
- Fixed a build error

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

 Documentation/sparc/adi.txt | 288 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   2 +
 arch/sparc/include/asm/mmu_context_64.h |  32 
 arch/sparc/include/asm/pgtable_64.h |  94 ++-
 arch/sparc/include/asm/uaccess_64.h | 120 -
 arch/sparc/include/uapi/asm/auxvec.h|   8 +
 arch/sparc/include/uapi/asm/mman.h  |   2 +
 arch/sparc/kernel/Makefile  |   1 +
 arch/sparc/kernel/adi_64.c  |  93 +++
 arch/sparc/kernel/mdesc.c   |   4 +
 arch/sparc/kernel/process_64.c  |  21 +++
 arch/sparc/kernel/traps_64.c|  88 +-
 arch/sparc/mm/gup.c |  37 
 arch/sparc/mm/tlb.c |  28 
 include/linux/mm.h  |   2 +
 20 files changed, 921 insertions(+), 12 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

diff --git a/Documentation/sparc/adi.txt b/Documentation/sparc/adi.txt
new file mode 100644
index 000..ab3cd7f
--- /dev/null
+++ b/Documentation/sparc/adi.txt
@@ -0,0 +1,288 @@
+Application Data Integrity (ADI)
+
+
+SPARC M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once ADI is enabled and version tags are set for ranges of
+address space of a task, the processor will compare the tag in pointers
+to memory in these ranges to the version set by the application
+previously. Access to memory is granted only if the tag in given
+pointer matches the tag set by the application. In case of mismatch,
+processor raises an exception.
+
+Following steps must be taken by a task to enable ADI fully:
+
+1. Set the user mode PSTATE.mcde bit. This acts as master switch for
+   the task's entire address space to enable/disable ADI for the task.
+
+2. Set TTE.mcd bit on any TLB entries that correspond to the range of
+   addresses ADI is being enabled on. MMU checks the version tag only
+   on the pages that have TTE.mcd bit set.
+
+3. Set the version tag for virtual addresses using stxa instruction
+   and one of the MCD specific ASIs. Each stxa instruction sets the
+   given tag for one ADI block size number of bytes. This step must
+   be repeated for entire page to set tags for entire page.
+
+ADI block size for the platform is provided by the hypervisor to the
+kernel in machine description tables. Hypervisor also provides the
+number of top bits in the virtual address that specify the version tag.
+Once version tag has been set for a memory location, the tag is stored
+in the physical memory and the same tag must be present in the ADI
+version tag bits of the virtual address being presented to the MMU. For
+example on SPARC M7 processor, MMU uses bits 63-60 for version tags and
+ADI block size is same as cachelin

[PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-11 Thread Khalid Aziz
ity 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 hour 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//numa_maps.

---
Khalid Aziz (4):
  signals, sparc: Add signal codes for ADI violations
  mm: Add function to support extra actions on swap in/out
  sparc64: Add support for ADI register fields, ASIs and traps
  sparc64: Add support for ADI (Application Data Integrity)

 Documentation/sparc/adi.txt | 288 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 +
 arch/sparc/include/asm/elf_64.h |   8 +
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  40 -
 arch/sparc/include/asm/mmu_64.h |   2 +
 arch/sparc/include/asm/mmu_context_64.h |  32 
 arch/sparc/include/asm/pgtable_64.h |  96 ++-
 arch/sparc/include/asm/ttable.h |  10 ++
 arch/sparc/include/asm/uaccess_64.h | 120 -
 arch/sparc/include/uapi/asm/asi.h   |   5 +
 arch/sparc/include/uapi/asm/auxvec.h|   8 +
 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  |  93 +++
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   4 +
 arch/sparc/kernel/process_64.c  |  21 +++
 arch/sparc/kernel/sun4v_mcd.S   |  16 ++
 arch/sparc/kernel/traps_64.c| 142 +++-
 arch/sparc/kernel/ttable_64.S   |   6 +-
 arch/sparc/mm/gup.c |  37 
 arch/sparc/mm/tlb.c |  28 
 arch/x86/kernel/signal_compat.c |   2 +-
 include/asm-generic/pgtable.h   |   5 +
 include/linux/mm.h  |   2 +
 include/uapi/asm-generic/siginfo.h  |   5 +-
 mm/memory.c |   2 +-
 mm/rmap.c   |   4 +-
 33 files changed, 1041 insertions(+), 19 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.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-06 Thread Khalid Aziz

On 01/06/2017 10:54 AM, Rob Gardner wrote:

On 01/06/2017 09:10 AM, Khalid Aziz wrote:

On 01/06/2017 10:02 AM, David Miller wrote:

From: Dave Hansen <dave.han...@linux.intel.com>
Date: Fri, 6 Jan 2017 08:55:03 -0800


Actually, that reminds me...  How does your code interface with
ksm?  Or
is there no interaction needed since you're always working on virtual
addresses?


This reminds me, I consider this feature potentially extremely useful
for
kernel debugging.  So I would like to make sure we don't implement
anything
in a way which would preclude that in the long term.


I agree and please do point out if I have made any implementation
decisions that could preclude that.

Thanks,
Khalid



Khalid, I have already pointed out an implementation decision that
interferes with the potential for kernel debugging with ADI: lazy
clearing of version tags.


This does not preclude kernel debugging. If kernel debugging ends up 
requiring tags be cleared whenever a page is freed, we can add that code 
as part of kernel debugging support code and enable it conditionally 
only when kernel is being debugged. Forcing every task to incur the 
large cost of clearing tags on every "free" all the time is just not an 
acceptable cost only to support kernel debugging. It should be a dynamic 
switch to be toggled on only when debugging kernel. PSTATE.mcde being 
set is not enough to trigger a trap. It is easy enough to clear TTE.mcd 
before block initialization of a page and avoid a trap due to tag 
mismatch, or just use physical address with block initialization.


We can evaluate all of these options when we get to implementing kernel 
debugging using ADI.


Thanks,
Khalid




Details: when memory is "freed" the version tags are left alone, as it
is an expensive operation to go through the memory and clear the tag for
each cache line. So this is done lazily whenever memory is "allocated".
More specifically, the first time a user process touches freshly
allocated memory, a fault occurs and the kernel then clears the page. In
the NG4 and M7 variants of clear_user_page, the block init store ASI is
used to optimize, and it has the side effect of clearing the ADI tag for
the cache line. BUT only if pstate.mcde is clear. If pstate.mcde is set,
then instead of the ADI tag being cleared, the tag is *checked*, and if
there is a mismatch between the version in the virtual address and the
version in memory, then you'll get a trap and panic. Therefore, with
this design, you cannot have pstate.mcde enabled while in the kernel (in
general). To solve this you have to check the state of pstate.mcde (or
just turn it off) before doing any block init store in clear_user_page,
memset, memcpy, etc.

Rob

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-06 Thread Khalid Aziz

On 01/06/2017 10:02 AM, David Miller wrote:

From: Dave Hansen 
Date: Fri, 6 Jan 2017 08:55:03 -0800


Actually, that reminds me...  How does your code interface with ksm?  Or
is there no interaction needed since you're always working on virtual
addresses?


This reminds me, I consider this feature potentially extremely useful for
kernel debugging.  So I would like to make sure we don't implement anything
in a way which would preclude that in the long term.


I agree and please do point out if I have made any implementation 
decisions that could preclude that.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-06 Thread Khalid Aziz

On 01/06/2017 09:55 AM, Dave Hansen wrote:

On 01/06/2017 08:22 AM, Khalid Aziz wrote:

On 01/06/2017 08:36 AM, Dave Hansen wrote:

On 01/06/2017 07:32 AM, Khalid Aziz wrote:

I agree with you on simplicity first. Subpage granularity is complex,
but the architecture allows for subpage granularity. Maybe the right
approach is to support this at page granularity first for swappable
pages and then expand to subpage granularity in a subsequent patch?
Pages locked in memory can already use subpage granularity with my
patch.


What do you mean by "locked in memory"?  mlock()'d memory can still be
migrated around and still requires "swap" ptes, for instance.


You are right. Page migration can invalidate subpage granularity even
for locked pages. Is it possible to use cpusets to keep a task and its
memory locked on a single node?


It's going to be hard to impossible to guarantee.  mlock() doesn't
guarantee that things won't change physical addresses.  You'd have to
change that guarantee or chase all the things in the kernel that might
change physical addresses (compaction, ksm, etc...).

Actually, that reminds me...  How does your code interface with ksm?  Or
is there no interaction needed since you're always working on virtual
addresses?



Yes, version tags are interpreted at virtual address level.

--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-06 Thread Khalid Aziz

On 01/06/2017 08:36 AM, Dave Hansen wrote:

On 01/06/2017 07:32 AM, Khalid Aziz wrote:

I agree with you on simplicity first. Subpage granularity is complex,
but the architecture allows for subpage granularity. Maybe the right
approach is to support this at page granularity first for swappable
pages and then expand to subpage granularity in a subsequent patch?
Pages locked in memory can already use subpage granularity with my patch.


What do you mean by "locked in memory"?  mlock()'d memory can still be
migrated around and still requires "swap" ptes, for instance.


You are right. Page migration can invalidate subpage granularity even 
for locked pages. Is it possible to use cpusets to keep a task and its 
memory locked on a single node? Just wondering if there are limited 
cases where subpage granularity could work without supporting subpage 
granularity for tags in swap. It still sounds like the right thing to do 
is to get a reliable implementation in place with page size granularity 
and then add the complexity of subpage granularity.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-06 Thread Khalid Aziz

On 01/06/2017 02:19 AM, Michal Hocko wrote:

On Thu 05-01-17 13:30:10, Khalid Aziz wrote:
[...]

It is very tempting to restrict tags to PAGE_SIZE granularity since it makes
code noticeably simpler and that is indeed going to be the majority of
cases. Sooner or later somebody would want to use multiple tags per page
though.


I didn't get to read the patch throughly yet but I am really confused by
this statement. The api is mprotect based which makes it ineherently
PAGE_SIZE granular. How do you want to achieve cache line granularity
with this API?

And I would really vote for simplicity first... Subpage granularity
sounds way too tricky...



Hi Michal,

ADI can be enabled for subsets of a task's address space. It takes three 
steps to enable ADI completely:


1. Enable the task to use ADI by setting PSTATE.mcde bit. This is the 
master switch for ADI. mprotect() does this in my patch. Granularity for 
this operation is entire address space for the task.


2. Set TTE.mcd bit for each page translation for the pages one wants ADI 
enabled on. mprotect() does this as well in my patch. Granularity for 
this operation is per page.


3. Set version tag for the addresses task wants to enable ADI on using 
"stxa" instruction. This is done entirely in userspace with no 
assistance or intervention needed from the kernel. Granularity for this 
operation is cache line size which is 64 bytes on Sparc M7.


I agree with you on simplicity first. Subpage granularity is complex, 
but the architecture allows for subpage granularity. Maybe the right 
approach is to support this at page granularity first for swappable 
pages and then expand to subpage granularity in a subsequent patch? 
Pages locked in memory can already use subpage granularity with my patch.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-05 Thread Khalid Aziz

On 01/05/2017 12:22 PM, Dave Hansen wrote:

On 01/04/2017 04:26 PM, Khalid Aziz wrote:
...

No, we do not have space to stuff PAGE_SIZE/64 version tags in swap pte.
There is enough space for just one tag per page. DaveM had suggested
doing this since the usual case is for a task to set one tag per page
even though MMU does not require it. I have implemented this as first
pass to start a discussion and get feedback on whether rest of the
swapping implementation and other changes look right, hence the patch is
"RFC". If this all looks good, I can expand swapping support in a
subsequent patch or iteration of this patch to allocate space in
mm_context_t possibly to store per cacheline tags. I am open to any
other ideas on storing this larger number of version tags.


FWIW, This is the kind of thing that would be really useful to point out
to reviewers instead of requiring them to ferret it out of the code.  It
has huge implications for how applications use this feature.


Hi Dave,

Thanks for taking the time to review this. I appreciate your patience. I 
will add more details.




As for where to store the tags...  It's potentially a *lot* of data, so
I think it'll be a pain any way you do it.

If you, instead, can live with doing things on a PAGE_SIZE granularity
like pkeys does, you could just store it in the VMA and have the kernel
tag the data at the same time it zeroes the pages.


It is very tempting to restrict tags to PAGE_SIZE granularity since it 
makes code noticeably simpler and that is indeed going to be the 
majority of cases. Sooner or later somebody would want to use multiple 
tags per page though. There can be 128 4-bit tags per 8K page which 
requires 64 bytes of tag storage for each page. This can add up. What I 
am considering doing is store the tag in swp pte if I find only one tag 
on the page. A VMA can cover multiple pages and we have unused bits in 
swp pte. It makes more sense to store the tags in swp pte. If I find 
more than one tag on the page, I can allocate memory, attach it to a 
data structure in mm_context_t and store the tags there. I will need to 
use an rb tree or some other way to keep the data sorted to make it 
quick to retrieve the tags for one of the millions of pages a task might 
have. As I said, it gets complex trying to store tags per cacheline as 
opposed to per page :)


--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-05 Thread Khalid Aziz

On 01/05/2017 02:37 AM, Jerome Marchand wrote:

On 01/04/2017 11:46 PM, Khalid Aziz wrote:

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.

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.  It also adds handlers for all traps
related to MCD. 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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v2:
- Fixed a build error

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

 Documentation/sparc/adi.txt | 239 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 ++
 arch/sparc/include/asm/elf_64.h |   8 ++
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  40 +-
 arch/sparc/include/asm/mmu_64.h |   2 +
 arch/sparc/include/asm/mmu_context_64.h |  32 +
 arch/sparc/include/asm/pgtable_64.h |  97 -
 arch/sparc/include/asm/ttable.h |  10 ++
 arch/sparc/include/asm/uaccess_64.h | 120 +++-
 arch/sparc/include/uapi/asm/asi.h   |   5 +
 arch/sparc/include/uapi/asm/auxvec.h|   8 ++
 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  |  93 +
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   4 +
 arch/sparc/kernel/process_64.c  |  21 +++
 arch/sparc/kernel/sun4v_mcd.S   |  16 +++
 arch/sparc/kernel/traps_64.c| 142 ++-
 arch/sparc/kernel/ttable_64.S   |   6 +-
 arch/sparc/mm/gup.c |  37 +
 arch/sparc/mm/tlb.c |  28 
 arch/x86/kernel/signal_compat.c |   2 +-
 include/asm-generic/pgtable.h   |   5 +
 include/linux/mm.h  |   2 +
 include/uapi/asm-generic/siginfo.h  |   5 +-
 mm/memory.c |   2 +-
 mm/rmap.c   |   4 +-


I haven't actually reviewed the code and looked at why you need
set_swp_pte_at() function, but the code that add the generic version of
this function need to be separated from the rest of the patch. Also,
given the size of this patch, I suspect the rest also need to be broken
into more patches.

Jerome



Sure, I can do that. Code to add new signal codes can be one patch, 
generic changes to swap infrastructure can be another and I can look for 
logical breaks for the rest of the sparc specific code.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-04 Thread Khalid Aziz

On 01/04/2017 04:49 PM, Dave Hansen wrote:

On 01/04/2017 03:44 PM, Rob Gardner wrote:

On 01/04/2017 03:40 PM, Dave Hansen wrote:

On 01/04/2017 03:35 PM, Rob Gardner wrote:

Tags are not cleared at all when memory is freed, but rather, lazily
(and automatically) cleared when memory is allocated.

What does "allocated" mean in this context?  Physical or virtual? What
does this do, for instance?


The first time a virtual page is touched by a process after the malloc,
the kernel does clear_user_page() or something similar, which zeroes the
memory. At the same time, the memory tags are cleared.


OK, so the tags can't survive a MADV_FREE.  That's definitely something
for apps to understand that use MADV_FREE as a substitute for memset().
It also means that tags can't be set for physically unallocated memory.

Neither of those are deal killers, but it would be nice to document it.


This can go into the adi.txt doc file.



How does this all work with large pages?


It works with large pages the same way as normal sized pages. The TTE 
for a large page also will have the mcd bit set in it and tags are set 
and referenced the same way.


--
Khalid



--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-04 Thread Khalid Aziz

On 01/04/2017 04:31 PM, Dave Hansen wrote:

One other high-level comment:  It would be nice to see the
arch-independent and x86 portions broken out and explained in their own
right, even if they're small patches.  It's a bit cruel to make us
scroll through a thousand lines of sparc code to see the bits
interesting to us.


Sure, that is very reasonable. I will do that.



It would also be really nice to see a high-level breakdown explaining
what you had to modify, especially since this affects all of the system
calls that take a PROT_* argument.  The sample code is nice, but it's no
substitute for writing it down.


I will expand the explanation in Documentation/sparc/adi.txt.

Thanks!

--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-04 Thread Khalid Aziz

On 01/04/2017 04:27 PM, Dave Hansen wrote:

On 01/04/2017 02:46 PM, Khalid Aziz wrote:

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.


I'm a bit confused why we need all the mechanics with set_swp_pte_at().
For pkeys, for instance, all of the PTEs under a given VMA share a pkey.
 When swapping something in, we just get the pkey out of the VMA and
populate the PTE.

ADI doesn't seem to have a similar restriction.  The feature is turned
on or off at a VMA granularity, but we do not (or can enforce that all
pages under a given VMA must share a tag.

But this leads to an interesting question: is the tag associated with
the (populated?) pte, or the virtual address?  Can you have tags
associated with non-present addresses?  What's the mechanism that clears
the tags at munmap() or MADV_FREE time?


Hi Dave,

Tag is associated with virtual address and all pages in a singular VMA 
do not share the same tag. When a page is swapped out, we need to save 
the tag that was set on it so we can restore it when we bring the page 
back in. When MMU translates a vitrtual address into physical address, 
it expects to see the same tag set on the physical page as is set in the 
VA before it will allow access. Tags are cleared on a page by 
NG4clear_page() and NG4clear_user_page() when a page is allocated to a task.




Is the tag storage a precious resource?  Can it be exhausted?


There is a metadata area in RAM that stores the tags and it has enough 
space to cover all the tags for the RAM size.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v3] sparc64: Add support for Application Data Integrity (ADI)

2017-01-04 Thread Khalid Aziz
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.

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.  It also adds handlers for all traps
related to MCD. 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.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
---
v2:
- Fixed a build error

v3:
- Removed CONFIG_SPARC_ADI
- Replaced prctl commands with mprotect
- Added auxiliary vectors for ADI parameters
- Enabled ADI for swappable pages

 Documentation/sparc/adi.txt | 239 
 arch/sparc/include/asm/adi.h|   6 +
 arch/sparc/include/asm/adi_64.h |  46 ++
 arch/sparc/include/asm/elf_64.h |   8 ++
 arch/sparc/include/asm/hugetlb.h|  13 ++
 arch/sparc/include/asm/hypervisor.h |   2 +
 arch/sparc/include/asm/mman.h   |  40 +-
 arch/sparc/include/asm/mmu_64.h |   2 +
 arch/sparc/include/asm/mmu_context_64.h |  32 +
 arch/sparc/include/asm/pgtable_64.h |  97 -
 arch/sparc/include/asm/ttable.h |  10 ++
 arch/sparc/include/asm/uaccess_64.h | 120 +++-
 arch/sparc/include/uapi/asm/asi.h   |   5 +
 arch/sparc/include/uapi/asm/auxvec.h|   8 ++
 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  |  93 +
 arch/sparc/kernel/entry.h   |   3 +
 arch/sparc/kernel/head_64.S |   1 +
 arch/sparc/kernel/mdesc.c   |   4 +
 arch/sparc/kernel/process_64.c  |  21 +++
 arch/sparc/kernel/sun4v_mcd.S   |  16 +++
 arch/sparc/kernel/traps_64.c| 142 ++-
 arch/sparc/kernel/ttable_64.S   |   6 +-
 arch/sparc/mm/gup.c |  37 +
 arch/sparc/mm/tlb.c |  28 
 arch/x86/kernel/signal_compat.c |   2 +-
 include/asm-generic/pgtable.h   |   5 +
 include/linux/mm.h  |   2 +
 include/uapi/asm-generic/siginfo.h  |   5 +-
 mm/memory.c |   2 +-
 mm/rmap.c   |   4 +-
 33 files changed, 993 insertions(+), 19 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

diff --git a/Documentation/sparc/adi.txt b/Documentation/sparc/adi.txt
new file mode 100644
index 000..18aa6d0
--- /dev/null
+++ b/Documentation/sparc/adi.txt
@@ -0,0 +1,239 @@
+Application Data Integrity (ADI)
+
+
+Sparc M7 processor adds the Application Data Integrity (ADI) feature.
+ADI allows a task to set version tags on any subset of its address
+space. Once ADI is enabled and version tags are set for ranges of
+address space of a task, the processor will compare the tag in pointers
+to memory in these ranges to the version set by the application
+previously. Access to memory is granted only if the tag in given
+pointer matches the tag set by the application. In case of mismatch,
+processor raises an exception.
+
+Following steps must be taken by a task to enable ADI fully:
+
+1. Set the user mode PSTATE.mcde bit
+
+2. Set TTE.mcd bit on any TLB entries that correspond to the range of
+addresses ADI is being enabled on.
+
+3. Set the version tag for memory addresses.
+
+ADI is enabled on a set of pages using mprotect() with PROT_ADI flag.
+When ADI is enabled on a set of pages by a task for the first time,
+kernel sets the PSTATE.mcde bit fot the task. Version tags for memory
+addresses are set with an stxa instruction on the addresses using
+ASI_MCD_PRIMARY or ASI_MCD_ST_BLKINIT_PRIMARY. Version tags are
+specified in bits 63-60 of address and are set on memory the size of ADI
+block size.  ADI block size is provided by the hypervisor to the kernel.
+Kernel returns the value of ADI block size to userspace using auxiliary
+vector along with other ADI inf

Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-08 Thread Khalid Aziz

On 03/08/2016 01:27 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Tue, 8 Mar 2016 13:16:11 -0700


On 03/08/2016 12:57 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 14:06:43 -0700


Good questions. Isn't set of valid VAs already constrained by VA_BITS
(set to 44 in arch/sparc/include/asm/processor_64.h)? As I see it we
are already not using the top 4 bits. Please correct me if I am wrong.


Another limiting constraint is the number of address bits coverable by
the 4-level page tables we use.  And this is sign extended so we have
a top-half and a bottom-half with a "hole" in the center of the VA
space.

I want some clarification on the top bits during ADI accesses.

If ADI is enabled, then the top bits of the virtual address are
intepreted as tag bits.  Once "verified" with the ADI settings, what
happense to these tag bits?  Are they dropped from the virtual address
before being passed down the TLB et al. for translations?


Bits 63-60 (tag bits) are dropped from the virtual address before
being passed down the TLB for translation when PSTATE.mcde = 1.


Ok and you said that values 15 and 0 are special.

I'm just wondering if this means you can't really use ADI mappings in
the top half of the 64-bit address space.  If the bits are dropped, they
will be zero, but they need to be all 1's for the top-half of the VA
space since it's sign extended.



According to the manual when PSTATE.mcde=1, bits 63:60 of the virtual 
address of any load or store (using virtual address) are masked before 
being sent to memory system which includes MMU. Hardware TSB walker 
masks bits 63:60 and then sign extends from bit 59 before generating TSB 
pointer and before comparison to TSB TTE VAs but the virtual address in 
the TTE tag that is written to DTLB is masked and not sign extended. 
Manual also states that for implementations that fully support 60 bits 
or more of virtual address, they must sign-extend virtual address in TSB 
TTE tag.


--
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-08 Thread Khalid Aziz

On 03/08/2016 12:57 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 14:06:43 -0700


Good questions. Isn't set of valid VAs already constrained by VA_BITS
(set to 44 in arch/sparc/include/asm/processor_64.h)? As I see it we
are already not using the top 4 bits. Please correct me if I am wrong.


Another limiting constraint is the number of address bits coverable by
the 4-level page tables we use.  And this is sign extended so we have
a top-half and a bottom-half with a "hole" in the center of the VA
space.

I want some clarification on the top bits during ADI accesses.

If ADI is enabled, then the top bits of the virtual address are
intepreted as tag bits.  Once "verified" with the ADI settings, what
happense to these tag bits?  Are they dropped from the virtual address
before being passed down the TLB et al. for translations?


Bits 63-60 (tag bits) are dropped from the virtual address before being 
passed down the TLB for translation when PSTATE.mcde = 1.


--
Khalid



If not, then this means you have to map ADI memory to the correct
location so that the tags match up.

And if that's the case, if you really wanted to mix tags within a
single page, you'd have to map that page several times, once for each
and every cacheline granular tag you'd like to use within that page.



--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 12:16 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 11:24:54 -0700


Tags can be cleared by user by setting tag to 0. Tags are
automatically cleared by the hardware when the mapping for a virtual
address is removed from TSB (which is why swappable pages are a
problem), so kernel does not have to do it as part of clean up.


You might be able to crib some bits for the Tag in the swp_entry_t, it's
64-bit and you can therefore steal bits from the offset field.

That way you'll have the ADI tag in the page tables, ready to re-install
at swapin time.



Hi Dave,

Can we enable ADI support for swappable pages in a subsequent update 
after the core functionality is stable on mlock'd pages?


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 12:16 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 11:24:54 -0700


Tags can be cleared by user by setting tag to 0. Tags are
automatically cleared by the hardware when the mapping for a virtual
address is removed from TSB (which is why swappable pages are a
problem), so kernel does not have to do it as part of clean up.


You might be able to crib some bits for the Tag in the swp_entry_t, it's
64-bit and you can therefore steal bits from the offset field.

That way you'll have the ADI tag in the page tables, ready to re-install
at swapin time.



That is a possibility but limited in scope. An address range covered by 
a single TTE can have large number of tags. Version tags are set on 
cacheline. In extreme case, one could set a tag for each set of 64-bytes 
in a page. Also tags are set completely in userspace and no transition 
occurs to kernel space, so kernel has no idea of what tags have been 
set. I have not found a way to query the MMU on tags.


I will think some more about it.

Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 01:58 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 13:41:39 -0700


Shared data may not always be backed by a file. My understanding is
one of the use cases is for in-memory databases. This shared space
could also be used to hand off transactions in flight to other
processes. These transactions in flight would not be backed by a
file. Some of these use cases might not use shmfs even. Setting ADI
bits at virtual address level catches all these cases since what backs
the tagged virtual address can be anything - a mapped file, mmio
space, just plain chunk of memory.


Frankly the most interesting use case to me is simply finding bugs
and memory scribbles, and for that we're want to be able to ADI
arbitrary memory returned from malloc() and friends.

I personally see ADI more as a debugging than a security feature,
but that's just my view.



I think that is a very strong use case. It can be a very effective tool 
for debugging especially when it comes to catching wild writes.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 11:49 AM, Andy Lutomirski wrote:

On Mon, Mar 7, 2016 at 10:22 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

No, it changes the tag associated with the virtual address for the caller.
Physical page backing this virtual address is unaffected. Tag checking is
done for virtual addresses. The one restriction where physical address is
relevant is when two processes map the same physical page, they both have to
use the same tag for the virtual addresses that map on to the shared
physical pages.


Slow down, please.  *Why* do the tags for two different VAs that map
to the same PA have to match?  What goes wrong if they don't, and why
is requiring them to be the same a good idea?



Consider this scenario:

1. Process A creates a shm and attaches to it.
2. Process A fills shm with data it wants to share with only known 
processes. It enables ADI and sets tags on the shm.
3. Hacker triggers something like stack overflow on process A, exec's a 
new rogue binary and manages to attach to this shm. MMU knows tags were 
set on the virtual address mapping to the physical pages hosting the 
shm. If MMU does not require the rogue process to set the exact same 
tags on its mapping of the same shm, rogue process has defeated the ADI 
protection easily.


Does this make sense?





I sense DoS issues in your future.



Are you concerned about DoS even if the tag is associated with virtual
address, not physical address?


Yes, absolutely.

fd = open("/lib/ld.so");
mmap(fd)
stxa to write the tag

*boom*, presumably, because the tags apparently have to match for all mappings.



A process can not just write version tags and make the file inaccessible 
to others. It takes three steps to enable ADI:


1. Set PSTATE.mcde for the process.
2. Set TTE.mcd on all PTEs for the virtual addresses ADI is being 
enabled on.

3. Set version tags.

Unless all three steps are taken, tag checking will not be done. stxa 
will fail unless step 2 is completed. In your example, the step of 
setting TTE.mcd will force sharing to stop for the process through 
change_protection(), right?


Thanks for asking these tough questions. These are very helpful in 
refining my implementation and avoiding silly bugs.


--
Khalid


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 11:09 AM, Rob Gardner wrote:

On 03/07/2016 10:04 AM, Khalid Aziz wrote:

On 03/07/2016 09:56 AM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 08:07:53 -0700


PR_GET_SPARC_ADICAPS


Put this into a new ELF auxiliary vector entry via ARCH_DLINFO.

So now all that's left is supposedly the TAG stuff, please explain
that to me so I can direct you to the correct existing interface to
provide that as well.

Really, try to avoid prtctl, it's poorly typed and almost worse than
ioctl().



The two remaining operations I am looking at are:

1. Is PSTATE.mcde bit set for the process? PR_SET_SPARC_ADI provides
this in its return value in the patch I sent.

2. Is TTE.mcd set for a given virtual address? PR_GET_SPARC_ADI_STATUS
provides this function in the patch I sent.

Setting and clearing version tags can be done entirely from userspace:

while (addr < end) {
asm volatile(
"stxa %1, [%0]ASI_MCD_PRIMARY\n\t"
:
: "r" (addr), "r" (version));
addr += adicap.blksz;
}
so I do not have to add any kernel code for tags.



What about clearing the tags when the user is done with the memory? You
can't count on the user to do that, so doesn't the kernel have to do it
someplace?



Tags can be cleared by user by setting tag to 0. Tags are automatically 
cleared by the hardware when the mapping for a virtual address is 
removed from TSB (which is why swappable pages are a problem), so kernel 
does not have to do it as part of clean up.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 11:08 AM, Andy Lutomirski wrote:

On Mon, Mar 7, 2016 at 10:04 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

On 03/07/2016 09:56 AM, David Miller wrote:


From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 08:07:53 -0700


PR_GET_SPARC_ADICAPS



Put this into a new ELF auxiliary vector entry via ARCH_DLINFO.

So now all that's left is supposedly the TAG stuff, please explain
that to me so I can direct you to the correct existing interface to
provide that as well.

Really, try to avoid prtctl, it's poorly typed and almost worse than
ioctl().



The two remaining operations I am looking at are:

1. Is PSTATE.mcde bit set for the process? PR_SET_SPARC_ADI provides this in
its return value in the patch I sent.

2. Is TTE.mcd set for a given virtual address? PR_GET_SPARC_ADI_STATUS
provides this function in the patch I sent.

Setting and clearing version tags can be done entirely from userspace:

 while (addr < end) {
 asm volatile(
 "stxa %1, [%0]ASI_MCD_PRIMARY\n\t"
 :
 : "r" (addr), "r" (version));
 addr += adicap.blksz;
 }
so I do not have to add any kernel code for tags.


Is the effect of that to change the tag associated with a page to
which the caller has write access?


No, it changes the tag associated with the virtual address for the 
caller. Physical page backing this virtual address is unaffected. Tag 
checking is done for virtual addresses. The one restriction where 
physical address is relevant is when two processes map the same physical 
page, they both have to use the same tag for the virtual addresses that 
map on to the shared physical pages.




I sense DoS issues in your future.



Are you concerned about DoS even if the tag is associated with virtual 
address, not physical address?


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 09:45 AM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Mon, 7 Mar 2016 08:07:53 -0700


I can remove CONFIG_SPARC_ADI. It does mean this code will be built
into 32-bit kernels as well but it will be inactive code.


The code should be built only into obj-$(CONFIG_SPARC64) just like the
rest of the 64-bit specific code.  I don't know why in the world you
would build it into the 32-bit kernel.



You are right. I did not understand you correctly the first time.

Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 08:43 AM, Andy Lutomirski wrote:

On Mon, Mar 7, 2016 at 7:30 AM, Rob Gardner <rob.gard...@oracle.com> wrote:

On 03/07/2016 07:07 AM, Khalid Aziz wrote:


On 03/05/2016 09:07 PM, David Miller wrote:


From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed,  2 Mar 2016 13:39:37 -0700


 In this
 first implementation I am enabling ADI for hugepages only
 since these pages are locked in memory and hence avoid the
 issue of saving and restoring tags.



This makes the feature almost entire useless.

Non-hugepages must be in the initial implementation.



Hi David,

Thanks for the feedback. I will get this working for non-hugepages as
well. ADI state of each VMA region is already stored in the VMA itself in my
first implementation, so I do not lose it when the page is swapped out. The
trouble is ADI version tags for each VMA region have to be stored on the
swapped out pages since the ADI version tags are flushed when TLB entry for
a page is flushed.




Khalid,

Are you sure about that last statement? My understanding is that the tags
are stored in physical memory, and remain there until explicitly changed or
removed, and so flushing a TLB entry has no effect on the ADI tags. If it
worked the way you think, then somebody would have to potentially reload a
long list of ADI tags on every TLB miss.



I'll bite, since this was sent to linux-api:

Can someone explain what this feature does for the benefit of people
who haven't read the manual (and who don't even know where to find the
manual)?

Are the top few bits of a sparc64 virtual address currently
must-be-zero?  Does this feature change the semantics so that those
bits are ignored for address resolution and instead must match
whatever the ADI tag is determined to be during address resolution?

Is this enforced for both user and kernel accesses?

Is the actual ADI tag associated with a "page" associated with the
page of physical memory or is it associated with a mapping?  That is,
if there are two virtual aliases of the same physical page (in the
same process or otherwise), does the hardware require them to have the
same ADI tag?  If the answer is no, then IMO this is definitely
something that should use mprotect and you should seriously consider
using something like mprotect_key (new syscall, not in Linus' tree
yet) for it.  In fact, you might consider a possible extra parameter
to that syscall for this purpose.

Cc: Dave Hansen.  It seems to be the zeitgeist to throw tag bits at
PTEs these days.



Hi Andy,

The primary purpose of this feature is to prevent rogue accesses to 
memory regions. If a database were to allocate memory pages to cache 
database, it can enable ADI on those pages and set version tags. Version 
tag for a memory address is encoded in bits 63-60 in the virtual 
address. When accessing an ADI enabled memory region, top 4 bits of the 
virtual address presented to the MMU must match the version tag set 
earlier. When these bits do not match a tag, an MCD (Memory Corruption 
Detected) exception is raised. Kernel sends a SIGBUS to the offending 
process in response. There is some more info on ADI at 
<https://swisdev.oracle.com/_files/What-Is-ADI.html>.


Top 4-bits of sparc64 virtual address are used for version tag only when 
a process has its PSTATE.mcde bit set and it is accessing a memory 
region that has ADI enabled on it (TTE.mcd set) and a version tag was 
set on the virtual address being accessed. These 4-bits retain their 
original semantics in all other cases.


ADI version tags are checked for data fetches only. My implementation 
enforces this for userspace addresses only. Expanding this to include 
kernel data addresses as well will be a good thing to do to protect 
kernel data but I want to try to do this incrementally - (1) ADI for 
userspace addresses only for mlock'd pages, (2) expand support to 
swappable pages, (3) ADI for kernel data pages, (4)..whatever else 
makes sense...


ADI version tag applies to virtual addresses only. If two processes have 
virtual addresses mapping to the same physical page, they must use the 
same tag. Hardware will send MCD exception if the tags do not match. 
This was done to ensure a hack does not bypass ADI protection by simply 
inserting another VA-to-PA mapping. I do like the idea of mprotect() as 
David suggested and it can be done with existing mprotect() call. I will 
have to add a new key PROT_ADI to support this.


Thanks,
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-07 Thread Khalid Aziz

On 03/07/2016 08:30 AM, Rob Gardner wrote:

On 03/07/2016 07:07 AM, Khalid Aziz wrote:

On 03/05/2016 09:07 PM, David Miller wrote:

From: Khalid Aziz <khalid.a...@oracle.com>
Date: Wed,  2 Mar 2016 13:39:37 -0700


In this
first implementation I am enabling ADI for hugepages only
since these pages are locked in memory and hence avoid the
issue of saving and restoring tags.


This makes the feature almost entire useless.

Non-hugepages must be in the initial implementation.


Hi David,

Thanks for the feedback. I will get this working for non-hugepages as
well. ADI state of each VMA region is already stored in the VMA itself
in my first implementation, so I do not lose it when the page is
swapped out. The trouble is ADI version tags for each VMA region have
to be stored on the swapped out pages since the ADI version tags are
flushed when TLB entry for a page is flushed.



Khalid,

Are you sure about that last statement? My understanding is that the
tags are stored in physical memory, and remain there until explicitly
changed or removed, and so flushing a TLB entry has no effect on the ADI
tags. If it worked the way you think, then somebody would have to
potentially reload a long list of ADI tags on every TLB miss.

Rob



Hi Rob,

I am fairly sure that is the case. This is what I found from the 
processor guys and others working on ADI. I tested it out by setting up 
ADI on normal malloc'd pages that got swapped out and I got MCD 
exceptions when those pages were swapped back in on access.


I mis-spoke when I said "ADI version tags are flushed when TLB entry 
for a page is flushed". I meant ADI version tags are flushed when 
mapping for a virtual address is removed from TSB, not when TLB entry is 
flushed. Yes, ADI tags are stored in physical memory and removed when 
mapping is removed.


Thanks,
Khalid

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] sparc64: Add support for Application Data Integrity (ADI)

2016-03-03 Thread Khalid Aziz

On 03/02/2016 05:48 PM, Julian Calaby wrote:

Hi Khalid,

On Thu, Mar 3, 2016 at 11:25 AM, Khalid Aziz <khalid.a...@oracle.com> wrote:

Thanks, Julian! I really appreciate your feedback.


No problem!


My comments below.

On 03/02/2016 04:08 PM, Julian Calaby wrote:


Hi Khalid,

On Thu, Mar 3, 2016 at 7:39 AM, Khalid Aziz <khalid.a...@oracle.com>
wrote:



Enable Application Data Integrity (ADI) support in the sparc
kernel for applications to use ADI in userspace. ADI is a new
feature supported on sparc M7 and newer processors. ADI is supported
for data fetches only and not instruction fetches. This patch adds
prctl commands to enable and disable ADI (TSTATE.mcde), return ADI
parameters to userspace, enable/disable MCD (Memory Corruption
Detection) on selected memory ranges and enable TTE.mcd in PTEs. It
also adds handlers for all traps related to MCD. ADI is not enabled
by default for any task and a task must explicitly enable ADI
(TSTATE.mcde), turn MCD on on a memory range and set version tag
for ADI to be effective for the task. This patch adds support for
ADI for hugepages only. Addresses passed into system calls must be
non-ADI tagged addresses.



I can't comment on the actual functionality here, but I do see a few
minor style issues in your patch.

My big concern is that you're defining a lot of new code that is ADI
specific but isn't inside a CONFIG_SPARC_ADI ifdef. (That said,
handling ADI specific traps if ADI isn't enabled looks like a good
idea to me, however most of the other stuff is just dead code if
CONFIG_SPARC_ADI isn't enabled.)



Some of the code will be executed when CONFIG_SPARC_ADI is not enabled, for
instance init_adi() which will parse machine description to determine if
platform supports ADI. On the other hand, it might still make sense to
enclose this code in #ifdef. More on that below.





Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
---
NOTES: ADI is a new feature added to M7 processor to allow hardware
  to catch rogue accesses to memory. An app can enable ADI on
  its data pages, set version tags on them and use versioned
  addresses (bits 63-60 of the address contain a version tag)
  to access the data pages. If a rogue app attempts to access
  ADI enabled data pages, its access is blocked and processor
  generates an exception. Enabling this functionality for all
  data pages of an app requires adding infrastructure to save
  version tags for any data pages that get swapped out and
  restoring those tags when pages are swapped back in. In this
  first implementation I am enabling ADI for hugepages only
  since these pages are locked in memory and hence avoid the
  issue of saving and restoring tags. Once this core functionality
  is stable, ADI for other memory pages can be enabled more
  easily.

v2:
  - Fixed a build error

   Documentation/prctl/sparc_adi.txt |  62 ++
   Documentation/sparc/adi.txt   | 206
+++
   arch/sparc/Kconfig|  12 ++
   arch/sparc/include/asm/hugetlb.h  |  14 +++
   arch/sparc/include/asm/hypervisor.h   |   2 +
   arch/sparc/include/asm/mmu_64.h   |   1 +
   arch/sparc/include/asm/pgtable_64.h   |  15 +++
   arch/sparc/include/asm/processor_64.h |  19 +++
   arch/sparc/include/asm/ttable.h   |  10 ++
   arch/sparc/include/uapi/asm/asi.h |   3 +
   arch/sparc/include/uapi/asm/pstate.h  |  10 ++
   arch/sparc/kernel/entry.h |   3 +
   arch/sparc/kernel/head_64.S   |   1 +
   arch/sparc/kernel/mdesc.c |  81 +
   arch/sparc/kernel/process_64.c| 222
++
   arch/sparc/kernel/sun4v_mcd.S |  16 +++
   arch/sparc/kernel/traps_64.c  |  96 ++-
   arch/sparc/kernel/ttable_64.S |   6 +-
   include/linux/mm.h|   2 +
   include/uapi/asm-generic/siginfo.h|   5 +-
   include/uapi/linux/prctl.h|  16 +++
   kernel/sys.c  |  30 +
   22 files changed, 826 insertions(+), 6 deletions(-)
   create mode 100644 Documentation/prctl/sparc_adi.txt
   create mode 100644 Documentation/sparc/adi.txt
   create mode 100644 arch/sparc/kernel/sun4v_mcd.S



I must admit that I'm slightly impressed that the documentation is
over a quarter of the lines added. =)


diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 56442d2..0aac0ae 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -80,6 +80,7 @@ config SPARC64
  select NO_BOOTMEM
  select HAVE_ARCH_AUDITSYSCALL
  select ARCH_SUPPORTS_ATOMIC_RMW
+   select SPARC_ADI



This doesn't look right.


   config ARCH_DEFCONFIG
  string
@@ -314,6 +315,17 @@ if SPARC64
   source "kernel/power/Kconfig"
   endif

+config SPARC_ADI
+   bool "Application Data Inte

Re: [PATCH] sparc64: Add support for Application Data Integrity (ADI)

2016-03-02 Thread Khalid Aziz

On 03/02/2016 01:26 PM, kbuild test robot wrote:

Hi Khalid,

[auto build test ERROR on sparc/master]
[also build test ERROR on v4.5-rc6]
[cannot apply to next-20160302]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Khalid-Aziz/sparc64-Add-support-for-Application-Data-Integrity-ADI/20160303-025709
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git master
config: sparc64-allnoconfig (attached as .config)
reproduce:
 wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=sparc64

All errors (new ones prefixed by >>):

arch/sparc/kernel/process_64.c: In function 'disable_sparc_adi':

arch/sparc/kernel/process_64.c:961:6: error: implicit declaration of function 
'vma_policy' [-Werror=implicit-function-declaration]

  vma_policy(vma), vma->vm_userfaultfd_ctx);
  ^
arch/sparc/kernel/process_64.c:959:10: error: passing argument 9 of 
'vma_merge' makes pointer from integer without a cast [-Werror]
   prev = vma_merge(mm, prev, addr, end, vma->vm_flags,
  ^
In file included from arch/sparc/kernel/process_64.c:18:0:
include/linux/mm.h:1922:31: note: expected 'struct mempolicy *' but 
argument is of type 'int'
 extern struct vm_area_struct *vma_merge(struct mm_struct *,
   ^


Not sure why it built without errors on my system. I will #include 
 and send updated patch.


--
Khalid
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] sparc64: Add support for Application Data Integrity (ADI)

2016-03-02 Thread Khalid Aziz

Enable Application Data Integrity (ADI) support in the sparc
kernel for applications to use ADI in userspace. ADI is a new
feature supported on sparc M7 and newer processors. ADI is supported
for data fetches only and not instruction fetches. This patch adds
prctl commands to enable and disable ADI (TSTATE.mcde), return ADI
parameters to userspace, enable/disable MCD (Memory Corruption
Detection) on selected memory ranges and enable TTE.mcd in PTEs. It
also adds handlers for all traps related to MCD. ADI is not enabled
by default for any task and a task must explicitly enable ADI
(TSTATE.mcde), turn MCD on on a memory range and set version tag
for ADI to be effective for the task. This patch adds support for
ADI for hugepages only. Addresses passed into system calls must be
non-ADI tagged addresses.

Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
---
NOTES: ADI is a new feature added to M7 processor to allow hardware
to catch rogue accesses to memory. An app can enable ADI on
its data pages, set version tags on them and use versioned
addresses (bits 63-60 of the address contain a version tag)
to access the data pages. If a rogue app attempts to access
ADI enabled data pages, its access is blocked and processor
generates an exception. Enabling this functionality for all
data pages of an app requires adding infrastructure to save
version tags for any data pages that get swapped out and
restoring those tags when pages are swapped back in. In this
first implementation I am enabling ADI for hugepages only
since these pages are locked in memory and hence avoid the
issue of saving and restoring tags. Once this core functionality
is stable, ADI for other memory pages can be enabled more
easily.

 Documentation/prctl/sparc_adi.txt |  62 ++
 Documentation/sparc/adi.txt   | 206 +++
 arch/sparc/Kconfig|  12 ++
 arch/sparc/include/asm/hugetlb.h  |  14 +++
 arch/sparc/include/asm/hypervisor.h   |   2 +
 arch/sparc/include/asm/mmu_64.h   |   1 +
 arch/sparc/include/asm/pgtable_64.h   |  15 +++
 arch/sparc/include/asm/processor_64.h |  19 +++
 arch/sparc/include/asm/ttable.h   |  10 ++
 arch/sparc/include/uapi/asm/asi.h |   3 +
 arch/sparc/include/uapi/asm/pstate.h  |  10 ++
 arch/sparc/kernel/entry.h |   3 +
 arch/sparc/kernel/head_64.S   |   1 +
 arch/sparc/kernel/mdesc.c |  81 +
 arch/sparc/kernel/process_64.c| 221 ++
 arch/sparc/kernel/sun4v_mcd.S |  16 +++
 arch/sparc/kernel/traps_64.c  |  96 ++-
 arch/sparc/kernel/ttable_64.S |   6 +-
 include/linux/mm.h|   2 +
 include/uapi/asm-generic/siginfo.h|   5 +-
 include/uapi/linux/prctl.h|  16 +++
 kernel/sys.c  |  30 +
 22 files changed, 825 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/prctl/sparc_adi.txt
 create mode 100644 Documentation/sparc/adi.txt
 create mode 100644 arch/sparc/kernel/sun4v_mcd.S

diff --git a/Documentation/prctl/sparc_adi.txt 
b/Documentation/prctl/sparc_adi.txt
new file mode 100644
index 000..9cbdcae
--- /dev/null
+++ b/Documentation/prctl/sparc_adi.txt
@@ -0,0 +1,62 @@
+
+Overview
+
+
+SPARC M7 processor includes the feature Application Data Integrity (ADI).
+ADI allows a tag to be associated with a virtual memory address range
+and a process must access that memory range with the correct tag. ADI
+tag is embedded in bits 63-60 of virtual address. Once ADI is enabled
+on a range of memory addresses, the process can set a tag for blocks
+in this memory range n the cache using ASI_MCD_PRIMARY or
+ASI_MCD_ST_BLKINIT_PRIMARY. This tag is set for ADI block sized blocks
+which is provided to the kernel by machine description table.
+
+Linux kernel supports an application enabling and setting the ADI tag
+for a subset of its data pages. Those data pages have to be locked in
+memory since saving ADI tags to swap is not supported.
+
+
+New prctl options for ADI
+-
+
+Following new options to prctl() have been added to support ADI.
+
+   PR_GET_SPARC_ADICAPS - Get ADI capabilities for the processor.
+   These capabilities are used to set up ADI correctly
+   from userspace. Machine description table provides all
+   of the ADI capabilities information. arg2 to prctl() is
+   a pointer to struct adi_caps which is defined in
+   linux/prctl.h.
+
+
+   PR_SET_SPARC_ADI - Set the state of ADI in a user thread by
+   setting PSTATE.mcde bit in the user mode PSTATE register
+   of the calling thread based on the value passed in arg2:
+   1 == enable, 0 == disable, other == no change
+