Thread (11 messages) flat view 11 messages, 4 authors, 2017-08-04

Re: [PATCH v1 1/3] arch/powerpc/set_memory: Implement set_memory_xx routines

From: Aneesh Kumar K.V <hidden>
Date: 2017-08-04 03:39:16

Balbir Singh [off-list ref] writes:
On Wed, Aug 2, 2017 at 8:09 PM, Aneesh Kumar K.V
[off-list ref] wrote:
quoted
Balbir Singh [off-list ref] writes:
quoted
Add support for set_memory_xx routines. With the STRICT_KERNEL_RWX
feature support we got support for changing the page permissions
for pte ranges. This patch adds support for both radix and hash
so that we can change their permissions via set/clear masks.

A new helper is required for hash (hash__change_memory_range()
is changed to hash__change_boot_memory_range() as it deals with
bolted PTE's).

hash__change_memory_range() works with vmalloc'ed PAGE_SIZE requests
for permission changes. hash__change_memory_range() does not invoke
updatepp, instead it changes the software PTE and invalidates the PTE.

For radix, radix__change_memory_range() is setup to do the right
thing for vmalloc'd addresses. It takes a new parameter to decide
what attributes to set.
....
quoted
+int hash__change_memory_range(unsigned long start, unsigned long end,
+                             unsigned long set, unsigned long clear)
+{
+     unsigned long idx;
+     pgd_t *pgdp;
+     pud_t *pudp;
+     pmd_t *pmdp;
+     pte_t *ptep;
+
+     start = ALIGN_DOWN(start, PAGE_SIZE);
+     end = PAGE_ALIGN(end); // aligns up
+
+     /*
+      * Update the software PTE and flush the entry.
+      * This should cause a new fault with the right
+      * things setup in the hash page table
+      */
+     pr_debug("Changing flags on range %lx-%lx setting 0x%lx removing 0x%lx\n",
+              start, end, set, clear);
+
+     for (idx = start; idx < end; idx += PAGE_SIZE) {
quoted
+             pgdp = pgd_offset_k(idx);
+             pudp = pud_alloc(&init_mm, pgdp, idx);
+             if (!pudp)
+                     return -1;
+             pmdp = pmd_alloc(&init_mm, pudp, idx);
+             if (!pmdp)
+                     return -1;
+             ptep = pte_alloc_kernel(pmdp, idx);
+             if (!ptep)
+                     return -1;
+             hash__pte_update(&init_mm, idx, ptep, clear, set, 0);
I think this does the needful, if H_PAGE_HASHPTE is set, the flush
will happen
quoted
quoted
+             hash__flush_tlb_kernel_range(idx, idx + PAGE_SIZE);
+     }
You can use find_linux_pte_or_hugepte. with my recent patch series
find_init_mm_pte() ?
for pte_mkwrite and pte_wrprotect?
For walking page table. I am not sure you really want to allocate page
table in that function. If you do, then what will be the initial value
of PTE ? We are requesting to set an clear from and existing PTE entry
right ? If you find a none page table entry you should handle it via a
fault ?


-aneesh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help