Skip to content

Commit 062e825

Browse files
chleroympe
authored andcommitted
powerpc/603: Inconditionally use task PGDIR in DTLB misses
At the time being, DATA TLB miss handlers use task PGDIR for user addresses and swapper_pg_dir for kernel addresses. Now that kernel part of swapper_pg_dir is copied into task PGDIR at PGD allocation, it is possible to avoid the above logic and always use task PGDIR. But new kernel PGD entries can still be created after init, in which case those PGD entries may miss in task PGDIR. This can be handled in DATA TLB error handler. However, it needs to be done in real mode because the missing entry might be related to the stack. So implement copy of missing PGD entry in DATA TLB miss handler just after detection of invalid PGD entry. Also replace comparison by same calculation as in previous patch to know if an address belongs to a kernel or user segment. Note that as mentioned in platforms/Kconfig.cputype, SMP is not supported on 603 processors so there is no risk of the PGD entry be populated during the fault. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/a2ba8eeb1c845eeb9e46b6fe3a5e9f841df9a033.1724173828.git.christophe.leroy@csgroup.eu
1 parent 3f57d90 commit 062e825

1 file changed

Lines changed: 38 additions & 27 deletions

File tree

arch/powerpc/kernel/head_book3s_32.S

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -469,27 +469,22 @@ InstructionAddressInvalid:
469469
DataLoadTLBMiss:
470470
/* Get PTE (linux-style) and check access */
471471
mfspr r0,SPRN_DMISS
472-
lis r1, TASK_SIZE@h /* check if kernel address */
473-
cmplw 0,r1,r0
474472
mfspr r2, SPRN_SDR1
475-
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
476-
rlwinm r2, r2, 28, 0xfffff000
477-
li r3, 3
478-
bgt- 112f
479-
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
480-
li r3, 0
481-
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
482-
112: rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
483-
lwz r2,0(r2) /* get pmd entry */
473+
rlwinm r1, r2, 28, 0xfffff000
474+
rlwimi r1,r0,12,20,29 /* insert top 10 bits of address */
475+
lwz r2,0(r1) /* get pmd entry */
476+
rlwinm r3, r0, 4, 0xf
484477
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
485-
beq- DataAddressInvalid /* return if no mapping */
486-
rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
478+
subi r3, r3, (TASK_SIZE >> 28) & 0xf
479+
beq- 2f /* bail if no mapping */
480+
1: rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
487481
lwz r2,0(r2) /* get linux-style pte */
482+
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
488483
andc. r1,r1,r2 /* check access & ~permission */
489484
bne- DataAddressInvalid /* return if access not permitted */
490485
/* Convert linux-style PTE to low word of PPC-style PTE */
491486
rlwinm r1,r2,32-9,30,30 /* _PAGE_WRITE -> PP msb */
492-
rlwimi r2,r3,0,30,31 /* userspace ? -> PP */
487+
rlwimi r2,r3,2,30,31 /* userspace ? -> PP */
493488
rlwimi r1,r2,32-3,24,24 /* _PAGE_WRITE -> _PAGE_DIRTY */
494489
xori r1,r1,_PAGE_DIRTY /* clear dirty when not rw */
495490
ori r1,r1,0xe04 /* clear out reserved bits */
@@ -518,6 +513,16 @@ MMU_FTR_SECTION_ELSE
518513
tlbld r0
519514
rfi
520515
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
516+
517+
2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
518+
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
519+
rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
520+
lwz r2,0(r2) /* get pmd entry */
521+
cmpwi cr0,r2,0
522+
beq- DataAddressInvalid /* return if no mapping */
523+
stw r2,0(r1)
524+
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
525+
b 1b
521526
DataAddressInvalid:
522527
mfspr r3,SPRN_SRR1
523528
rlwinm r1,r3,9,6,6 /* Get load/store bit */
@@ -543,26 +548,22 @@ DataAddressInvalid:
543548
DataStoreTLBMiss:
544549
/* Get PTE (linux-style) and check access */
545550
mfspr r0,SPRN_DMISS
546-
lis r1, TASK_SIZE@h /* check if kernel address */
547-
cmplw 0,r1,r0
548551
mfspr r2, SPRN_SDR1
549-
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
550-
rlwinm r2, r2, 28, 0xfffff000
551-
li r3, 3
552-
bgt- 112f
553-
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
554-
li r3, 0
555-
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
556-
112: rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
557-
lwz r2,0(r2) /* get pmd entry */
552+
rlwinm r1, r2, 28, 0xfffff000
553+
rlwimi r1,r0,12,20,29 /* insert top 10 bits of address */
554+
lwz r2,0(r1) /* get pmd entry */
555+
rlwinm r3, r0, 4, 0xf
558556
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
559-
beq- DataAddressInvalid /* return if no mapping */
557+
subi r3, r3, (TASK_SIZE >> 28) & 0xf
558+
beq- 2f /* bail if no mapping */
559+
1:
560560
rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
561561
lwz r2,0(r2) /* get linux-style pte */
562+
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
562563
andc. r1,r1,r2 /* check access & ~permission */
563564
bne- DataAddressInvalid /* return if access not permitted */
564565
/* Convert linux-style PTE to low word of PPC-style PTE */
565-
rlwimi r2,r3,0,31,31 /* userspace ? -> PP lsb */
566+
rlwimi r2,r3,1,31,31 /* userspace ? -> PP lsb */
566567
li r1,0xe06 /* clear out reserved bits & PP msb */
567568
andc r1,r2,r1 /* PP = user? 1: 0 */
568569
BEGIN_FTR_SECTION
@@ -592,6 +593,16 @@ MMU_FTR_SECTION_ELSE
592593
rfi
593594
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
594595

596+
2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
597+
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
598+
rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
599+
lwz r2,0(r2) /* get pmd entry */
600+
cmpwi cr0,r2,0
601+
beq- DataAddressInvalid /* return if no mapping */
602+
stw r2,0(r1)
603+
rlwinm r2,r2,0,0,19 /* extract address of pte page */
604+
b 1b
605+
595606
#ifndef CONFIG_ALTIVEC
596607
#define altivec_assist_exception unknown_exception
597608
#endif

0 commit comments

Comments
 (0)