Skip to content

Commit a9e00d8

Browse files
committed
s390/mm: Add huge page gmap linking support
Let's allow huge pmd linking when enabled through the KVM_CAP_S390_HPAGE_1M capability. Also we can now restrict gmap invalidation and notification to the cases where the capability has been activated and save some cycles when that's not the case. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com>
1 parent 7d735b9 commit a9e00d8

File tree

4 files changed

+13
-7
lines changed

4 files changed

+13
-7
lines changed

arch/s390/include/asm/mmu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ typedef struct {
2424
unsigned int uses_skeys:1;
2525
/* The mmu context uses CMM. */
2626
unsigned int uses_cmm:1;
27+
/* The gmaps associated with this context are allowed to use huge pages. */
28+
unsigned int allow_gmap_hpage_1m:1;
2729
} mm_context_t;
2830

2931
#define INIT_MM_CONTEXT(name) \

arch/s390/include/asm/mmu_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static inline int init_new_context(struct task_struct *tsk,
3232
mm->context.has_pgste = 0;
3333
mm->context.uses_skeys = 0;
3434
mm->context.uses_cmm = 0;
35+
mm->context.allow_gmap_hpage_1m = 0;
3536
#endif
3637
switch (mm->context.asce_limit) {
3738
case _REGION2_SIZE:

arch/s390/mm/gmap.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
/*
33
* KVM guest address space mapping code
44
*
5-
* Copyright IBM Corp. 2007, 2016
5+
* Copyright IBM Corp. 2007, 2016, 2018
66
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7+
* David Hildenbrand <david@redhat.com>
8+
* Janosch Frank <frankja@linux.vnet.ibm.com>
79
*/
810

911
#include <linux/kernel.h>
@@ -588,8 +590,8 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
588590
return -EFAULT;
589591
pmd = pmd_offset(pud, vmaddr);
590592
VM_BUG_ON(pmd_none(*pmd));
591-
/* large pmds cannot yet be handled */
592-
if (pmd_large(*pmd))
593+
/* Are we allowed to use huge pages? */
594+
if (pmd_large(*pmd) && !gmap->mm->context.allow_gmap_hpage_1m)
593595
return -EFAULT;
594596
/* Link gmap segment table entry location to page table. */
595597
rc = radix_tree_preload(GFP_KERNEL);
@@ -1632,6 +1634,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce,
16321634
unsigned long limit;
16331635
int rc;
16341636

1637+
BUG_ON(parent->mm->context.allow_gmap_hpage_1m);
16351638
BUG_ON(gmap_is_shadow(parent));
16361639
spin_lock(&parent->shadow_lock);
16371640
sg = gmap_find_shadow(parent, asce, edat_level);

arch/s390/mm/pgtable.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ static inline void pmdp_idte_local(struct mm_struct *mm,
347347
mm->context.asce, IDTE_LOCAL);
348348
else
349349
__pmdp_idte(addr, pmdp, 0, 0, IDTE_LOCAL);
350-
if (mm_has_pgste(mm))
350+
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
351351
gmap_pmdp_idte_local(mm, addr);
352352
}
353353

@@ -357,15 +357,15 @@ static inline void pmdp_idte_global(struct mm_struct *mm,
357357
if (MACHINE_HAS_TLB_GUEST) {
358358
__pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE,
359359
mm->context.asce, IDTE_GLOBAL);
360-
if (mm_has_pgste(mm))
360+
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
361361
gmap_pmdp_idte_global(mm, addr);
362362
} else if (MACHINE_HAS_IDTE) {
363363
__pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL);
364-
if (mm_has_pgste(mm))
364+
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
365365
gmap_pmdp_idte_global(mm, addr);
366366
} else {
367367
__pmdp_csp(pmdp);
368-
if (mm_has_pgste(mm))
368+
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
369369
gmap_pmdp_csp(mm, addr);
370370
}
371371
}

0 commit comments

Comments
 (0)