Re: [PATCH v5 4/4] sparc64: Add support for ADI (Application Data Integrity)
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? Rob -- 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)
On 01/25/2017 12:57 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. 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 Cc: Khalid Aziz --- 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
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7
On 01/13/2017 09:08 AM, Dave Hansen wrote: On 01/13/2017 07:29 AM, Rob Gardner wrote: so perhaps ADI should simply be disallowed for memory mapped to files, and this particular complication can be avoided. Thoughts? What's a "file" from your perspective? In Linux, shared memory is a file. hugetlbfs is done with files. Many databases mmap() their data into their address space. Of course I meant a traditional file is the DOS sense, ie, data stored on something magnetic. ;) But it doesn't really matter because I am just trying to envision a use case for any of the mmap scenarios. For instance a very persuasive use case for ADI is to 'color' malloc memory, freed malloc memory, and malloc's metadata with different ADI version tags so as to catch buffer overflows, underflows, use-after-free and use-after-realloc type scenarios. What is an equally compelling or even mildly interesting use case for ADI in shared memory and file mmap situations? Maybe you could mmap a file and immediately tag the entire thing with some version, thus disallowing all access to it, and then hand out access a chunk at a time. And then? Rob -- 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
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? 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. 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 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
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7
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. 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 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)
On 01/06/2017 10:18 AM, Khalid Aziz wrote: 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 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. I didn't say it precludes kernel debugging, just that it interferes, and there will be additional work to do if we want kernel debugging capability with ADI. Rob 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 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)
On 01/06/2017 09:10 AM, Khalid Aziz wrote: 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 Khalid, I have already pointed out an implementation decision that interferes with the potential for kernel debugging with ADI: lazy clearing of version tags. 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 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)
On 01/04/2017 04:01 PM, Dave Hansen wrote: On 01/04/2017 03:58 PM, Khalid Aziz wrote: 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. But does the user setting the tags need to know what the page size is? What if two different small pages have different tags and khugepaged comes along and tries to collapse them? Will the page be split if a user attempts to set two different tags inside two different small-page portions of a single THP? The MCD tags operate at a resolution of cache lines (64 bytes). Page sizes don't matter except that each virtual page must have a bit set in its TTE to allow MCD to be enabled on the page. Any page can have many different tags, one for each cache line. Rob -- 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)
On 01/04/2017 03: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. How does this all work with large pages? It all works completely with large pages. Rob -- 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)
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. Rob ptr = malloc(PAGE_SIZE); set_tag(ptr, 14); madvise(ptr, PAGE_SIZE, MADV_FREE); printf("tag: %d\n", get_tag(ptr)); free(ptr); -- 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)
On 01/04/2017 03: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? Is the tag storage a precious resource? Can it be exhausted? Tags are stored in physical memory, so there is no "tag storage" that can be exhausted. Tags are not cleared at all when memory is freed, but rather, lazily (and automatically) cleared when memory is allocated. Rob -- 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)
On 03/07/2016 10:39 AM, Khalid Aziz wrote: On 03/07/2016 11:12 AM, Dave Hansen wrote: On 03/07/2016 09:53 AM, Andy Lutomirski wrote: Also, what am I missing? Tying these tags to the physical page seems like a poor design to me. This seems really awkward to use. Yeah, can you describe the structures that store these things? Surely the hardware has some kind of lookup tables for them and stores them in memory _somewhere_. Version tags are tied to virtual addresses, not physical pages. Where exactly are the tags stored is part of processor architecture and I am not privy to that. MMU stores these lookup tables somewhere and uses it to authenticate access to virtual addresses. It really is irrelevant to kernel how MMU implements access controls as long as we have access to the knowledge of how to use it. The tags are stored in physical memory, and you can write a tag directly to that memory via stxa with ASI_MCD_REAL and completely bypass the MMU. When you do that, the tag will still be seen by any virtual address that maps to that physical address. Rob -- 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)
On 03/07/2016 10:24 AM, Khalid Aziz wrote: 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. I don't understand this. The hardware isn't involved when a mapping for a virtual address is removed from the TSB, so how could it automatically clear tags? Rob -- 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)
On 03/07/2016 01:38 PM, David Miller wrote: From: Khalid Aziz Date: Mon, 7 Mar 2016 14:33:56 -0700 On 03/07/2016 12:16 PM, David Miller wrote: From: Khalid Aziz 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. That would mean that ADI is impossible to use for swappable memory. ... If that's true I'm extremely disappointed that they devoted so much silicon and engineering to this feature yet didn't take that one critical step to make it generally useful. :( You can easily read ADI tags with a simple ldxa #ASI_MCD_PRIMARY instruction. Rob -- 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)
On 03/07/2016 01:33 PM, Khalid Aziz wrote: 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. To query the tag for a cache line, you just read it back with ldxa and ASI_MCD_PRIMARY (ie, asi 0x90), basically the same way you stored the tag in the first place. Rob -- 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)
On 03/07/2016 10:04 AM, Khalid Aziz wrote: On 03/07/2016 09:56 AM, David Miller wrote: From: Khalid Aziz 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? Rob -- 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)
On 03/07/2016 07:07 AM, Khalid Aziz wrote: On 03/05/2016 09:07 PM, David Miller wrote: From: Khalid Aziz 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 When that page is brought back in, its version tags have to be set up again. Version tags are set on cacheline boundary and hence there can be multiple version tags for a single page. Version tags have to be stored in the swap space somehow along with the page. I can start out with allowing ADI to be enabled only on pages locked in memory. +PR_ENABLE_SPARC_ADI - Enable ADI checking in all pages in the address +range specified. The pages in the range must be already +locked. This operation enables the TTE.mcd bit for the +pages specified. arg2 is the starting address for address +range and must be page aligned. arg3 is the length of +memory address range and must be a multiple of page size. I strongly dislike this interface, and it makes the prtctl cases look extremely ugly and hide to the casual reader what the code is actually doing. This is an mprotect() operation, so add a new flag bit and implement this via mprotect please. That is an interesting idea. Adding a PROT_ADI protection to mprotect() sounds cleaner. There are three steps to enabling ADI - (1) set PSTATE.mcde bit which is not tied to any VMA, (2) set TTE.mcd for each VMA, and (3) set the version tag on cacheline using MCD ASI. I can combine steps 1 and 2 in one mprotect() call. That will leave PR_GET_SPARC_ADICAPS and PR_GET_SPARC_ADI_STATUS prctl commands still to be implemented. PR_SET_SPARC_ADI is also used to check if the process has PSTATE.mcde bit set. I could use PR_GET_SPARC_ADI_STATUS to do that where return values of 0 and 1 mean the same as before and possibly add return value of 2 to mean PSTATE.mcde is not set? Then since you are guarenteed to have a consistent ADI setting for every single VMA region, you never "lose" the ADI state when you swap out. It's implicit in the VMA itself, because you'll store in the VMA that this is an ADI region. I also want this enabled unconditionally, without any Kconfig knobs. 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. 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