Skip to content

Commit 9f42f67

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon: "A pair of arm64 fixes for -rc3. The straightforward one is a fix to our firmware calling stub, which accidentally started corrupting the link register on machines with SVE. Since these machines don't really exist yet, it wasn't spotted in -next. The other fix is a revert-and-a-bit of a patch originally intended to allow PTE-level huge mappings for the VMAP area on 32-bit PPC 8xx. A side-effect of this change was that our pXd_set_huge() implementations could be replaced with generic dummy functions depending on the levels of page-table being used, which in turn broke the boot if we fail to create the linear mapping as a result of using these functions to operate on the pgd. Huge thanks to Michael Ellerman for modifying the revert so as not to regress PPC 8xx in terms of functionality. Anyway, that's the background and it's also available in the commit message along with Link tags pointing at all of the fun. Summary: - Fix hang when issuing SMC on SVE-capable system due to clobbered LR - Fix boot failure due to missing block mappings with folded page-table" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: Revert "mm/pgtable: add stubs for {pmd/pub}_{set/clear}_huge" arm64: smccc: Save lr before calling __arm_smccc_sve_check()
2 parents 7c14e4d + d8a7190 commit 9f42f67

File tree

5 files changed

+40
-59
lines changed

5 files changed

+40
-59
lines changed

arch/arm64/kernel/smccc-call.S

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,23 @@ SYM_FUNC_END(__arm_smccc_sve_check)
3232
EXPORT_SYMBOL(__arm_smccc_sve_check)
3333

3434
.macro SMCCC instr
35+
stp x29, x30, [sp, #-16]!
36+
mov x29, sp
3537
alternative_if ARM64_SVE
3638
bl __arm_smccc_sve_check
3739
alternative_else_nop_endif
3840
\instr #0
39-
ldr x4, [sp]
41+
ldr x4, [sp, #16]
4042
stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
4143
stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
42-
ldr x4, [sp, #8]
44+
ldr x4, [sp, #24]
4345
cbz x4, 1f /* no quirk structure */
4446
ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
4547
cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6
4648
b.ne 1f
4749
str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
48-
1: ret
50+
1: ldp x29, x30, [sp], #16
51+
ret
4952
.endm
5053

5154
/*

arch/arm64/mm/mmu.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,6 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
13391339
return dt_virt;
13401340
}
13411341

1342-
#if CONFIG_PGTABLE_LEVELS > 3
13431342
int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
13441343
{
13451344
pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot));
@@ -1354,16 +1353,6 @@ int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
13541353
return 1;
13551354
}
13561355

1357-
int pud_clear_huge(pud_t *pudp)
1358-
{
1359-
if (!pud_sect(READ_ONCE(*pudp)))
1360-
return 0;
1361-
pud_clear(pudp);
1362-
return 1;
1363-
}
1364-
#endif
1365-
1366-
#if CONFIG_PGTABLE_LEVELS > 2
13671356
int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
13681357
{
13691358
pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot));
@@ -1378,14 +1367,21 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
13781367
return 1;
13791368
}
13801369

1370+
int pud_clear_huge(pud_t *pudp)
1371+
{
1372+
if (!pud_sect(READ_ONCE(*pudp)))
1373+
return 0;
1374+
pud_clear(pudp);
1375+
return 1;
1376+
}
1377+
13811378
int pmd_clear_huge(pmd_t *pmdp)
13821379
{
13831380
if (!pmd_sect(READ_ONCE(*pmdp)))
13841381
return 0;
13851382
pmd_clear(pmdp);
13861383
return 1;
13871384
}
1388-
#endif
13891385

13901386
int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr)
13911387
{

arch/powerpc/mm/nohash/8xx.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,13 @@ void __init setup_kuap(bool disabled)
240240
mtspr(SPRN_MD_AP, MD_APG_KUAP);
241241
}
242242
#endif
243+
244+
int pud_clear_huge(pud_t *pud)
245+
{
246+
return 0;
247+
}
248+
249+
int pmd_clear_huge(pmd_t *pmd)
250+
{
251+
return 0;
252+
}

arch/x86/mm/pgtable.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,6 @@ int p4d_clear_huge(p4d_t *p4d)
682682
}
683683
#endif
684684

685-
#if CONFIG_PGTABLE_LEVELS > 3
686685
/**
687686
* pud_set_huge - setup kernel PUD mapping
688687
*
@@ -721,23 +720,6 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
721720
return 1;
722721
}
723722

724-
/**
725-
* pud_clear_huge - clear kernel PUD mapping when it is set
726-
*
727-
* Returns 1 on success and 0 on failure (no PUD map is found).
728-
*/
729-
int pud_clear_huge(pud_t *pud)
730-
{
731-
if (pud_large(*pud)) {
732-
pud_clear(pud);
733-
return 1;
734-
}
735-
736-
return 0;
737-
}
738-
#endif
739-
740-
#if CONFIG_PGTABLE_LEVELS > 2
741723
/**
742724
* pmd_set_huge - setup kernel PMD mapping
743725
*
@@ -768,6 +750,21 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
768750
return 1;
769751
}
770752

753+
/**
754+
* pud_clear_huge - clear kernel PUD mapping when it is set
755+
*
756+
* Returns 1 on success and 0 on failure (no PUD map is found).
757+
*/
758+
int pud_clear_huge(pud_t *pud)
759+
{
760+
if (pud_large(*pud)) {
761+
pud_clear(pud);
762+
return 1;
763+
}
764+
765+
return 0;
766+
}
767+
771768
/**
772769
* pmd_clear_huge - clear kernel PMD mapping when it is set
773770
*
@@ -782,7 +779,6 @@ int pmd_clear_huge(pmd_t *pmd)
782779

783780
return 0;
784781
}
785-
#endif
786782

787783
#ifdef CONFIG_X86_64
788784
/**

include/linux/pgtable.h

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,34 +1397,10 @@ static inline int p4d_clear_huge(p4d_t *p4d)
13971397
}
13981398
#endif /* !__PAGETABLE_P4D_FOLDED */
13991399

1400-
#ifndef __PAGETABLE_PUD_FOLDED
14011400
int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot);
1402-
int pud_clear_huge(pud_t *pud);
1403-
#else
1404-
static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
1405-
{
1406-
return 0;
1407-
}
1408-
static inline int pud_clear_huge(pud_t *pud)
1409-
{
1410-
return 0;
1411-
}
1412-
#endif /* !__PAGETABLE_PUD_FOLDED */
1413-
1414-
#ifndef __PAGETABLE_PMD_FOLDED
14151401
int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
1402+
int pud_clear_huge(pud_t *pud);
14161403
int pmd_clear_huge(pmd_t *pmd);
1417-
#else
1418-
static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
1419-
{
1420-
return 0;
1421-
}
1422-
static inline int pmd_clear_huge(pmd_t *pmd)
1423-
{
1424-
return 0;
1425-
}
1426-
#endif /* !__PAGETABLE_PMD_FOLDED */
1427-
14281404
int p4d_free_pud_page(p4d_t *p4d, unsigned long addr);
14291405
int pud_free_pmd_page(pud_t *pud, unsigned long addr);
14301406
int pmd_free_pte_page(pmd_t *pmd, unsigned long addr);

0 commit comments

Comments
 (0)