mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-22 22:04:47 +08:00
powerpc/32: Don't use a struct based type for pte_t
Long time ago we had a config item called STRICT_MM_TYPECHECKS to build the kernel with pte_t defined as a structure in order to perform additional build checks or build it with pte_t defined as a simple type in order to get simpler generated code. Commit670eea9241
("powerpc/mm: Always use STRICT_MM_TYPECHECKS") made the struct based definition the only one, considering that the generated code was similar in both cases. That's right on ppc64 because the ABI is such that the content of a struct having a single simple type element is passed as register, but on ppc32 such a structure is passed via the stack like any structure. Simple test function: pte_t test(pte_t pte) { return pte; } Before this patch we get c00108ec <test>: c00108ec: 81 24 00 00 lwz r9,0(r4) c00108f0: 91 23 00 00 stw r9,0(r3) c00108f4: 4e 80 00 20 blr So, for PPC32, restore the simple type behaviour we got before commit670eea9241
, but instead of adding a config option to activate type check, do it when __CHECKER__ is set so that type checking is performed by 'sparse' and provides feedback like: arch/powerpc/mm/pgtable.c:466:16: warning: incorrect type in return expression (different base types) arch/powerpc/mm/pgtable.c:466:16: expected unsigned long arch/powerpc/mm/pgtable.c:466:16: got struct pte_t [usertype] x With this patch we now get c0010890 <test>: c0010890: 4e 80 00 20 blr Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> [mpe: Define STRICT_MM_TYPECHECKS rather than repeating the condition] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/c904599f33aaf6bb7ee2836a9ff8368509e0d78d.1631887042.git.christophe.leroy@csgroup.eu
This commit is contained in:
parent
a61ec782a7
commit
c7d19189d7
@ -245,7 +245,7 @@ static int number_of_cells_per_pte(pmd_t *pmd, pte_basic_t val, int huge)
|
||||
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
|
||||
unsigned long clr, unsigned long set, int huge)
|
||||
{
|
||||
pte_basic_t *entry = &p->pte;
|
||||
pte_basic_t *entry = (pte_basic_t *)p;
|
||||
pte_basic_t old = pte_val(*p);
|
||||
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
|
||||
int num, i;
|
||||
|
@ -2,17 +2,33 @@
|
||||
#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
|
||||
#define _ASM_POWERPC_PGTABLE_TYPES_H
|
||||
|
||||
#if defined(__CHECKER__) || !defined(CONFIG_PPC32)
|
||||
#define STRICT_MM_TYPECHECKS
|
||||
#endif
|
||||
|
||||
/* PTE level */
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
|
||||
typedef struct { pte_basic_t pte, pte1, pte2, pte3; } pte_t;
|
||||
#else
|
||||
#elif defined(STRICT_MM_TYPECHECKS)
|
||||
typedef struct { pte_basic_t pte; } pte_t;
|
||||
#else
|
||||
typedef pte_basic_t pte_t;
|
||||
#endif
|
||||
|
||||
#if defined(STRICT_MM_TYPECHECKS) || \
|
||||
(defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES))
|
||||
#define __pte(x) ((pte_t) { (x) })
|
||||
static inline pte_basic_t pte_val(pte_t x)
|
||||
{
|
||||
return x.pte;
|
||||
}
|
||||
#else
|
||||
#define __pte(x) ((pte_t)(x))
|
||||
static inline pte_basic_t pte_val(pte_t x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PMD level */
|
||||
#ifdef CONFIG_PPC64
|
||||
|
@ -271,7 +271,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_
|
||||
{
|
||||
pmd_t *pmd = pmd_off(mm, addr);
|
||||
pte_basic_t val;
|
||||
pte_basic_t *entry = &ptep->pte;
|
||||
pte_basic_t *entry = (pte_basic_t *)ptep;
|
||||
int num, i;
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user