Skip to content

Commit 964c2c0

Browse files
Dominik Dingelfrankjaa
authored andcommitted
s390/mm: Clear huge page storage keys on enable_skey
When a guest starts using storage keys, we trap and set a default one for its whole valid address space. With this patch we are now able to do that for large pages. To speed up the storage key insertion, we use __storage_key_init_range, which in-turn will use sske_frame to set multiple storage keys with one instruction. As it has been previously used for debuging we have to get rid of the default key check and make it quiescing. Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com> Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com> [replaced page_set_storage_key loop with __storage_key_init_range] Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com>
1 parent 0959e16 commit 964c2c0

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

arch/s390/mm/gmap.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,17 +2539,43 @@ EXPORT_SYMBOL_GPL(s390_enable_sie);
25392539
* Enable storage key handling from now on and initialize the storage
25402540
* keys with the default key.
25412541
*/
2542-
static int __s390_enable_skey(pte_t *pte, unsigned long addr,
2543-
unsigned long next, struct mm_walk *walk)
2542+
static int __s390_enable_skey_pte(pte_t *pte, unsigned long addr,
2543+
unsigned long next, struct mm_walk *walk)
25442544
{
25452545
/* Clear storage key */
25462546
ptep_zap_key(walk->mm, addr, pte);
25472547
return 0;
25482548
}
25492549

2550+
static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
2551+
unsigned long hmask, unsigned long next,
2552+
struct mm_walk *walk)
2553+
{
2554+
pmd_t *pmd = (pmd_t *)pte;
2555+
unsigned long start, end;
2556+
2557+
/*
2558+
* The write check makes sure we do not set a key on shared
2559+
* memory. This is needed as the walker does not differentiate
2560+
* between actual guest memory and the process executable or
2561+
* shared libraries.
2562+
*/
2563+
if (pmd_val(*pmd) & _SEGMENT_ENTRY_INVALID ||
2564+
!(pmd_val(*pmd) & _SEGMENT_ENTRY_WRITE))
2565+
return 0;
2566+
2567+
start = pmd_val(*pmd) & HPAGE_MASK;
2568+
end = start + HPAGE_SIZE - 1;
2569+
__storage_key_init_range(start, end);
2570+
return 0;
2571+
}
2572+
25502573
int s390_enable_skey(void)
25512574
{
2552-
struct mm_walk walk = { .pte_entry = __s390_enable_skey };
2575+
struct mm_walk walk = {
2576+
.hugetlb_entry = __s390_enable_skey_hugetlb,
2577+
.pte_entry = __s390_enable_skey_pte,
2578+
};
25532579
struct mm_struct *mm = current->mm;
25542580
struct vm_area_struct *vma;
25552581
int rc = 0;

arch/s390/mm/pageattr.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
static inline unsigned long sske_frame(unsigned long addr, unsigned char skey)
1616
{
17-
asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0"
17+
asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0"
1818
: [addr] "+a" (addr) : [skey] "d" (skey));
1919
return addr;
2020
}
@@ -23,8 +23,6 @@ void __storage_key_init_range(unsigned long start, unsigned long end)
2323
{
2424
unsigned long boundary, size;
2525

26-
if (!PAGE_DEFAULT_KEY)
27-
return;
2826
while (start < end) {
2927
if (MACHINE_HAS_EDAT1) {
3028
/* set storage keys for a 1MB frame */
@@ -37,7 +35,7 @@ void __storage_key_init_range(unsigned long start, unsigned long end)
3735
continue;
3836
}
3937
}
40-
page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
38+
page_set_storage_key(start, PAGE_DEFAULT_KEY, 1);
4139
start += PAGE_SIZE;
4240
}
4341
}

0 commit comments

Comments
 (0)