Skip to content

Commit 0354486

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/mm: Add configurable STRICT_MM_TYPECHECKS
Add support for configurable STRICT_MM_TYPECHECKS. The s390 ABI defines that return values with complex types like structures and unions are returned in a return value buffer allocated by the caller. This is also true for small structures and unions which would fit into a register. On the other hand when such types are passed as arguments to functions they are passed in registers, if they are small enough. This leads to inefficient code when such a return value of a function call is then passed as argument to a subsequent function call. This is especially true for all mm types, like pte_t and others, which are only for type checking reasons defined as a structure. This however can be bypassed with the STRICT_MM_TYPECHECKS feature, which is used by a few other architectures, which seem to have the same problem. Add CONFIG_STRICT_MM_TYPECHECKS which can be used to change the type of pte_t and other structures. If the config option is not enabled the types are defined to unsigned long, allowing for better code generation, however there is no type checking anymore. If it is enabled the types are structures like before so that type checking is performed, but less efficient code is generated. The option is always enabled in debug_defconfig, and for convenience an mmtypes.config topic target is added, which allows to easily enable it, in case memory management code is changed. CONFIG_STRICT_MM_TYPECHECKS and STRICT_MM_TYPECHECKS are kept separate, since STRICT_MM_TYPECHECKS is common across architectures and common code. Therefore use the same define also for s390 code. Add CONFIG_STRICT_MM_TYPECHECKS to make it build time configurable. Reviewed-by: Alexander Gordeev <[email protected]> Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 94d553c commit 0354486

File tree

4 files changed

+43
-30
lines changed

4 files changed

+43
-30
lines changed

arch/s390/Kconfig.debug

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ config DEBUG_ENTRY
1313

1414
If unsure, say N.
1515

16+
config STRICT_MM_TYPECHECKS
17+
bool "Strict Memory Management Type Checks"
18+
depends on DEBUG_KERNEL
19+
help
20+
Enable strict type checking for memory management types like pte_t
21+
and pmd_t. This generates slightly worse code and should be used
22+
for debug builds.
23+
24+
If unsure, say N.
25+
1626
config CIO_INJECT
1727
bool "CIO Inject interfaces"
1828
depends on DEBUG_KERNEL && DEBUG_FS

arch/s390/configs/debug_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ CONFIG_SAMPLE_FTRACE_DIRECT=m
893893
CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m
894894
CONFIG_SAMPLE_FTRACE_OPS=m
895895
CONFIG_DEBUG_ENTRY=y
896+
CONFIG_STRICT_MM_TYPECHECKS=y
896897
CONFIG_CIO_INJECT=y
897898
CONFIG_KUNIT=m
898899
CONFIG_KUNIT_DEBUGFS=y

arch/s390/configs/mmtypes.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Help: Enable strict memory management typechecks
2+
CONFIG_STRICT_MM_TYPECHECKS=y

arch/s390/include/asm/page.h

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ static inline void copy_page(void *to, void *from)
7171
#define vma_alloc_zeroed_movable_folio(vma, vaddr) \
7272
vma_alloc_folio(GFP_HIGHUSER_MOVABLE | __GFP_ZERO, 0, vma, vaddr)
7373

74-
/*
75-
* These are used to make use of C type-checking..
76-
*/
74+
#ifdef CONFIG_STRICT_MM_TYPECHECKS
75+
#define STRICT_MM_TYPECHECKS
76+
#endif
77+
78+
#ifdef STRICT_MM_TYPECHECKS
7779

7880
typedef struct { unsigned long pgprot; } pgprot_t;
7981
typedef struct { unsigned long pgste; } pgste_t;
@@ -82,42 +84,40 @@ typedef struct { unsigned long pmd; } pmd_t;
8284
typedef struct { unsigned long pud; } pud_t;
8385
typedef struct { unsigned long p4d; } p4d_t;
8486
typedef struct { unsigned long pgd; } pgd_t;
85-
typedef pte_t *pgtable_t;
8687

87-
static inline unsigned long pgprot_val(pgprot_t pgprot)
88-
{
89-
return pgprot.pgprot;
88+
#define DEFINE_PGVAL_FUNC(name) \
89+
static __always_inline unsigned long name ## _val(name ## _t name) \
90+
{ \
91+
return name.name; \
9092
}
9193

92-
static inline unsigned long pgste_val(pgste_t pgste)
93-
{
94-
return pgste.pgste;
95-
}
94+
#else /* STRICT_MM_TYPECHECKS */
9695

97-
static inline unsigned long pte_val(pte_t pte)
98-
{
99-
return pte.pte;
100-
}
96+
typedef unsigned long pgprot_t;
97+
typedef unsigned long pgste_t;
98+
typedef unsigned long pte_t;
99+
typedef unsigned long pmd_t;
100+
typedef unsigned long pud_t;
101+
typedef unsigned long p4d_t;
102+
typedef unsigned long pgd_t;
101103

102-
static inline unsigned long pmd_val(pmd_t pmd)
103-
{
104-
return pmd.pmd;
104+
#define DEFINE_PGVAL_FUNC(name) \
105+
static __always_inline unsigned long name ## _val(name ## _t name) \
106+
{ \
107+
return name; \
105108
}
106109

107-
static inline unsigned long pud_val(pud_t pud)
108-
{
109-
return pud.pud;
110-
}
110+
#endif /* STRICT_MM_TYPECHECKS */
111111

112-
static inline unsigned long p4d_val(p4d_t p4d)
113-
{
114-
return p4d.p4d;
115-
}
112+
DEFINE_PGVAL_FUNC(pgprot)
113+
DEFINE_PGVAL_FUNC(pgste)
114+
DEFINE_PGVAL_FUNC(pte)
115+
DEFINE_PGVAL_FUNC(pmd)
116+
DEFINE_PGVAL_FUNC(pud)
117+
DEFINE_PGVAL_FUNC(p4d)
118+
DEFINE_PGVAL_FUNC(pgd)
116119

117-
static inline unsigned long pgd_val(pgd_t pgd)
118-
{
119-
return pgd.pgd;
120-
}
120+
typedef pte_t *pgtable_t;
121121

122122
#define __pgprot(x) ((pgprot_t) { (x) } )
123123
#define __pgste(x) ((pgste_t) { (x) } )

0 commit comments

Comments
 (0)