Skip to content

Commit 547e9fe

Browse files
committed
Merge branch 'dat-enhancement-1'
Heiko Carstens says: ==================== Add the Dat-Enhancement facility 1 to the list of facilities which are required to start the kernel. The facility provides the CSPG and IDTE instructions. In particular the CSPG instruction can be used to replace a valid page table entry with a different page table entry, which also differs in the page frame real address. Without the CSPG instruction it is possible to use the CSP instruction to change valid page table entries, however it only allows to change the lower or higher 32 bits of such entries, which means it cannot be used to change the page frame real address of valid page table entries. Given that there is code around (e.g. HugeTLB vmemmap optimization) which requires to change valid page table entries of the kernel mapping, without the detour over an invalid page table entry, make the CSPG instruction unconditionally available. The Dat-Enhancement facility 1 is available since z990, which is older than the currently supported minimum architecture (z10). Therefore adding this the architecture level set shouldn't cause any problems. ==================== Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
2 parents 020d5dc + 68807a8 commit 547e9fe

7 files changed

Lines changed: 16 additions & 62 deletions

File tree

arch/s390/include/asm/cpufeature.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ int cpu_have_feature(unsigned int nr);
2727
#define cpu_has_edat1() test_facility(8)
2828
#define cpu_has_edat2() test_facility(78)
2929
#define cpu_has_gs() test_facility(133)
30-
#define cpu_has_idte() test_facility(3)
3130
#define cpu_has_nx() test_facility(130)
3231
#define cpu_has_rdp() test_facility(194)
3332
#define cpu_has_seq_insn() test_facility(85)

arch/s390/include/asm/pgtable.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -648,18 +648,6 @@ static inline int mm_uses_skeys(struct mm_struct *mm)
648648
return 0;
649649
}
650650

651-
static inline void csp(unsigned int *ptr, unsigned int old, unsigned int new)
652-
{
653-
union register_pair r1 = { .even = old, .odd = new, };
654-
unsigned long address = (unsigned long)ptr | 1;
655-
656-
asm volatile(
657-
" csp %[r1],%[address]"
658-
: [r1] "+&d" (r1.pair), "+m" (*ptr)
659-
: [address] "d" (address)
660-
: "cc");
661-
}
662-
663651
/**
664652
* cspg() - Compare and Swap and Purge (CSPG)
665653
* @ptr: Pointer to the value to be exchanged
@@ -1402,7 +1390,6 @@ int set_pgste_bits(struct mm_struct *mm, unsigned long addr,
14021390
int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep);
14031391
int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc,
14041392
unsigned long *oldpte, unsigned long *oldpgste);
1405-
void gmap_pmdp_csp(struct mm_struct *mm, unsigned long vmaddr);
14061393
void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr);
14071394
void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr);
14081395
void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr);
@@ -1692,10 +1679,10 @@ static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)
16921679

16931680
#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */
16941681

1695-
static inline void __pmdp_csp(pmd_t *pmdp)
1682+
static inline void __pmdp_cspg(pmd_t *pmdp)
16961683
{
1697-
csp((unsigned int *)pmdp + 1, pmd_val(*pmdp),
1698-
pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
1684+
cspg((unsigned long *)pmdp, pmd_val(*pmdp),
1685+
pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
16991686
}
17001687

17011688
#define IDTE_GLOBAL 0

arch/s390/include/asm/tlbflush.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ static inline void __tlb_flush_idte(unsigned long asce)
3535
*/
3636
static inline void __tlb_flush_global(void)
3737
{
38-
unsigned int dummy = 0;
38+
unsigned long dummy = 0;
3939

40-
csp(&dummy, 0, 0);
40+
cspg(&dummy, 0, 0);
4141
}
4242

4343
/*
@@ -54,7 +54,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm)
5454
cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
5555
barrier();
5656
gmap_asce = READ_ONCE(mm->context.gmap_asce);
57-
if (cpu_has_idte() && gmap_asce != -1UL) {
57+
if (gmap_asce != -1UL) {
5858
if (gmap_asce)
5959
__tlb_flush_idte(gmap_asce);
6060
__tlb_flush_idte(mm->context.asce);
@@ -68,10 +68,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm)
6868

6969
static inline void __tlb_flush_kernel(void)
7070
{
71-
if (cpu_has_idte())
72-
__tlb_flush_idte(init_mm.context.asce);
73-
else
74-
__tlb_flush_global();
71+
__tlb_flush_idte(init_mm.context.asce);
7572
}
7673

7774
static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)

arch/s390/mm/gmap.c

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,7 @@ EXPORT_SYMBOL_GPL(gmap_create);
138138

139139
static void gmap_flush_tlb(struct gmap *gmap)
140140
{
141-
if (cpu_has_idte())
142-
__tlb_flush_idte(gmap->asce);
143-
else
144-
__tlb_flush_global();
141+
__tlb_flush_idte(gmap->asce);
145142
}
146143

147144
static void gmap_radix_tree_free(struct radix_tree_root *root)
@@ -1988,10 +1985,8 @@ static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new,
19881985
if (machine_has_tlb_guest())
19891986
__pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce,
19901987
IDTE_GLOBAL);
1991-
else if (cpu_has_idte())
1992-
__pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL);
19931988
else
1994-
__pmdp_csp(pmdp);
1989+
__pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL);
19951990
set_pmd(pmdp, new);
19961991
}
19971992

@@ -2012,7 +2007,7 @@ static void gmap_pmdp_clear(struct mm_struct *mm, unsigned long vmaddr,
20122007
_SEGMENT_ENTRY_GMAP_UC |
20132008
_SEGMENT_ENTRY));
20142009
if (purge)
2015-
__pmdp_csp(pmdp);
2010+
__pmdp_cspg(pmdp);
20162011
set_pmd(pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
20172012
}
20182013
spin_unlock(&gmap->guest_table_lock);
@@ -2032,17 +2027,6 @@ void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr)
20322027
}
20332028
EXPORT_SYMBOL_GPL(gmap_pmdp_invalidate);
20342029

2035-
/**
2036-
* gmap_pmdp_csp - csp all affected guest pmd entries
2037-
* @mm: pointer to the process mm_struct
2038-
* @vmaddr: virtual address in the process address space
2039-
*/
2040-
void gmap_pmdp_csp(struct mm_struct *mm, unsigned long vmaddr)
2041-
{
2042-
gmap_pmdp_clear(mm, vmaddr, 1);
2043-
}
2044-
EXPORT_SYMBOL_GPL(gmap_pmdp_csp);
2045-
20462030
/**
20472031
* gmap_pmdp_idte_local - invalidate and clear a guest pmd entry
20482032
* @mm: pointer to the process mm_struct
@@ -2066,7 +2050,7 @@ void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr)
20662050
if (machine_has_tlb_guest())
20672051
__pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE,
20682052
gmap->asce, IDTE_LOCAL);
2069-
else if (cpu_has_idte())
2053+
else
20702054
__pmdp_idte(gaddr, pmdp, 0, 0, IDTE_LOCAL);
20712055
*pmdp = __pmd(_SEGMENT_ENTRY_EMPTY);
20722056
}
@@ -2099,10 +2083,8 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr)
20992083
if (machine_has_tlb_guest())
21002084
__pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE,
21012085
gmap->asce, IDTE_GLOBAL);
2102-
else if (cpu_has_idte())
2103-
__pmdp_idte(gaddr, pmdp, 0, 0, IDTE_GLOBAL);
21042086
else
2105-
__pmdp_csp(pmdp);
2087+
__pmdp_idte(gaddr, pmdp, 0, 0, IDTE_GLOBAL);
21062088
*pmdp = __pmd(_SEGMENT_ENTRY_EMPTY);
21072089
}
21082090
spin_unlock(&gmap->guest_table_lock);

arch/s390/mm/pageattr.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,8 @@ static void pgt_set(unsigned long *old, unsigned long new, unsigned long addr,
7878
}
7979
table = (unsigned long *)((unsigned long)old & mask);
8080
crdte(*old, new, table, dtt, addr, get_lowcore()->kernel_asce.val);
81-
} else if (cpu_has_idte()) {
82-
cspg(old, *old, new);
8381
} else {
84-
csp((unsigned int *)old + 1, *old, new);
82+
cspg(old, *old, new);
8583
}
8684
}
8785

arch/s390/mm/pgtable.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,10 @@ static inline void pmdp_idte_global(struct mm_struct *mm,
360360
mm->context.asce, IDTE_GLOBAL);
361361
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
362362
gmap_pmdp_idte_global(mm, addr);
363-
} else if (cpu_has_idte()) {
363+
} else {
364364
__pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL);
365365
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
366366
gmap_pmdp_idte_global(mm, addr);
367-
} else {
368-
__pmdp_csp(pmdp);
369-
if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m)
370-
gmap_pmdp_csp(mm, addr);
371367
}
372368
}
373369

@@ -487,14 +483,8 @@ static inline void pudp_idte_global(struct mm_struct *mm,
487483
if (machine_has_tlb_guest())
488484
__pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE,
489485
mm->context.asce, IDTE_GLOBAL);
490-
else if (cpu_has_idte())
491-
__pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL);
492486
else
493-
/*
494-
* Invalid bit position is the same for pmd and pud, so we can
495-
* reuse _pmd_csp() here
496-
*/
497-
__pmdp_csp((pmd_t *) pudp);
487+
__pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL);
498488
}
499489

500490
static inline pud_t pudp_flush_direct(struct mm_struct *mm,

arch/s390/tools/gen_facilities.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static struct facility_def facility_defs[] = {
2929
.bits = (int[]){
3030
0, /* N3 instructions */
3131
1, /* z/Arch mode installed */
32+
3, /* dat-enhancement 1 */
3233
18, /* long displacement facility */
3334
21, /* extended-immediate facility */
3435
25, /* store clock fast */

0 commit comments

Comments
 (0)