forked from Minki/linux
powerpc fixes for 5.10 #3
Fix miscompilation with GCC 4.9 by using asm_goto_volatile for put_user(). A fix for an RCU splat at boot caused by a recent lockdep change. A fix for a possible deadlock in our EEH debugfs code. Several fixes for handling of _PAGE_ACCESSED on 32-bit platforms. A build fix when CONFIG_NUMA=n. Thanks to: Andreas Schwab, Christophe Leroy, Oliver O'Halloran, Qian Cai, Scott Cheloha. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAl+nxNcTHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgEWMD/0SVRMNlv5K4QYi38GPQMR/fZ20uyf6 oLlGNwrXxdYfZEQGvjJ4XiNVEVHmj+nylVyqmI3HnjLRpjmfLopZE5HuIHMknszw VaYZ/MwnbHcnIt8q/3xM56zpk2zJo9kK1FEItmupbWIbQirJyeE1CEpVI1LXn9FR 2hNSpSk6hhwI/xrT6L1exIReP0CFlsZCMCgNbP9vEDPqOorx3Wxf1uqznV9uZWaZ AzQwevh2OvYd/rcsDLMlisRWv+JJTBJp/CyvKvawow9Akh81dpic26FqPPVLZkkT maxY2uGLEyI/qpYFor7Fz1LanMbu3SnXT483Cu3jSv5wzL+2YcdmGsb0IMgqaFlQ os8waD9q3KDeohCqgqcEYdnkNUo3TQjFP8ilZYYQXQZVBlsWuHkv5k59Bc03aa1w OAAXvmv+SlhNuCDRZI0qQQbSFlIMIGaUo+RsUZ7WkXBnYE4SCmfykVvP8uB2Djsf 98F4dpfWGPDF4n+wothUBycjJa3NG3Ceset04r94KAMfp0SR73xYHHIRSR1Xa6Pj 1s8EQ0MNMgVb1UdJ3eJCRpfO6oU1p+V7cnVhYH9rTSKBGAoHAwnCh/Py6JPBMcea 8ydNkApKODdZ5d6/oHa4i5oXJTik34f5p3nrBNOWQlA/dCrQeZX7YbYlhCUi0/4U OCI4V3sEs+dIaQ== =IFi+ -----END PGP SIGNATURE----- Merge tag 'powerpc-5.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fixes from Michael Ellerman: - fix miscompilation with GCC 4.9 by using asm_goto_volatile for put_user() - fix for an RCU splat at boot caused by a recent lockdep change - fix for a possible deadlock in our EEH debugfs code - several fixes for handling of _PAGE_ACCESSED on 32-bit platforms - build fix when CONFIG_NUMA=n Thanks to Andreas Schwab, Christophe Leroy, Oliver O'Halloran, Qian Cai, and Scott Cheloha. * tag 'powerpc-5.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/numa: Fix build when CONFIG_NUMA=n powerpc/8xx: Manage _PAGE_ACCESSED through APG bits in L1 entry powerpc/8xx: Always fault when _PAGE_ACCESSED is not set powerpc/40x: Always fault when _PAGE_ACCESSED is not set powerpc/603: Always fault when _PAGE_ACCESSED is not set powerpc: Use asm_goto_volatile for put_user() powerpc/smp: Call rcu_cpu_starting() earlier powerpc/eeh_cache: Fix a possible debugfs deadlock
This commit is contained in:
commit
e942d75281
@ -63,7 +63,7 @@ static inline void restore_user_access(unsigned long flags)
|
|||||||
static inline bool
|
static inline bool
|
||||||
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
|
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
|
||||||
{
|
{
|
||||||
return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
|
return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xff000000),
|
||||||
"Bug: fault blocked by AP register !");
|
"Bug: fault blocked by AP register !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,19 +33,18 @@
|
|||||||
* respectively NA for All or X for Supervisor and no access for User.
|
* respectively NA for All or X for Supervisor and no access for User.
|
||||||
* Then we use the APG to say whether accesses are according to Page rules or
|
* Then we use the APG to say whether accesses are according to Page rules or
|
||||||
* "all Supervisor" rules (Access to all)
|
* "all Supervisor" rules (Access to all)
|
||||||
* Therefore, we define 2 APG groups. lsb is _PMD_USER
|
* _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say
|
||||||
* 0 => Kernel => 01 (all accesses performed according to page definition)
|
* "all User" rules, that will lead to NA for all.
|
||||||
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
|
* Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED
|
||||||
* 2-15 => Not Used
|
* 0 => Kernel => 11 (all accesses performed according as user iaw page definition)
|
||||||
|
* 1 => Kernel+Accessed => 01 (all accesses performed according to page definition)
|
||||||
|
* 2 => User => 11 (all accesses performed according as user iaw page definition)
|
||||||
|
* 3 => User+Accessed => 00 (all accesses performed as supervisor iaw page definition) for INIT
|
||||||
|
* => 10 (all accesses performed according to swaped page definition) for KUEP
|
||||||
|
* 4-15 => Not Used
|
||||||
*/
|
*/
|
||||||
#define MI_APG_INIT 0x40000000
|
#define MI_APG_INIT 0xdc000000
|
||||||
|
#define MI_APG_KUEP 0xde000000
|
||||||
/*
|
|
||||||
* 0 => Kernel => 01 (all accesses performed according to page definition)
|
|
||||||
* 1 => User => 10 (all accesses performed according to swaped page definition)
|
|
||||||
* 2-15 => Not Used
|
|
||||||
*/
|
|
||||||
#define MI_APG_KUEP 0x60000000
|
|
||||||
|
|
||||||
/* The effective page number register. When read, contains the information
|
/* The effective page number register. When read, contains the information
|
||||||
* about the last instruction TLB miss. When MI_RPN is written, bits in
|
* about the last instruction TLB miss. When MI_RPN is written, bits in
|
||||||
@ -106,25 +105,9 @@
|
|||||||
#define MD_Ks 0x80000000 /* Should not be set */
|
#define MD_Ks 0x80000000 /* Should not be set */
|
||||||
#define MD_Kp 0x40000000 /* Should always be set */
|
#define MD_Kp 0x40000000 /* Should always be set */
|
||||||
|
|
||||||
/*
|
/* See explanation above at the definition of MI_APG_INIT */
|
||||||
* All pages' PP data bits are set to either 000 or 011 or 001, which means
|
#define MD_APG_INIT 0xdc000000
|
||||||
* respectively RW for Supervisor and no access for User, or RO for
|
#define MD_APG_KUAP 0xde000000
|
||||||
* Supervisor and no access for user and NA for ALL.
|
|
||||||
* Then we use the APG to say whether accesses are according to Page rules or
|
|
||||||
* "all Supervisor" rules (Access to all)
|
|
||||||
* Therefore, we define 2 APG groups. lsb is _PMD_USER
|
|
||||||
* 0 => Kernel => 01 (all accesses performed according to page definition)
|
|
||||||
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
|
|
||||||
* 2-15 => Not Used
|
|
||||||
*/
|
|
||||||
#define MD_APG_INIT 0x40000000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 0 => No user => 01 (all accesses performed according to page definition)
|
|
||||||
* 1 => User => 10 (all accesses performed according to swaped page definition)
|
|
||||||
* 2-15 => Not Used
|
|
||||||
*/
|
|
||||||
#define MD_APG_KUAP 0x60000000
|
|
||||||
|
|
||||||
/* The effective page number register. When read, contains the information
|
/* The effective page number register. When read, contains the information
|
||||||
* about the last instruction TLB miss. When MD_RPN is written, bits in
|
* about the last instruction TLB miss. When MD_RPN is written, bits in
|
||||||
|
@ -39,9 +39,9 @@
|
|||||||
* into the TLB.
|
* into the TLB.
|
||||||
*/
|
*/
|
||||||
#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
|
#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
|
||||||
#define _PAGE_SPECIAL 0x0020 /* SW entry */
|
#define _PAGE_ACCESSED 0x0020 /* Copied to L1 APG 1 entry in I/DTLB */
|
||||||
#define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */
|
#define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */
|
||||||
#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
|
#define _PAGE_SPECIAL 0x0080 /* SW entry */
|
||||||
|
|
||||||
#define _PAGE_NA 0x0200 /* Supervisor NA, User no access */
|
#define _PAGE_NA 0x0200 /* Supervisor NA, User no access */
|
||||||
#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
|
#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
|
||||||
@ -59,11 +59,12 @@
|
|||||||
|
|
||||||
#define _PMD_PRESENT 0x0001
|
#define _PMD_PRESENT 0x0001
|
||||||
#define _PMD_PRESENT_MASK _PMD_PRESENT
|
#define _PMD_PRESENT_MASK _PMD_PRESENT
|
||||||
#define _PMD_BAD 0x0fd0
|
#define _PMD_BAD 0x0f90
|
||||||
#define _PMD_PAGE_MASK 0x000c
|
#define _PMD_PAGE_MASK 0x000c
|
||||||
#define _PMD_PAGE_8M 0x000c
|
#define _PMD_PAGE_8M 0x000c
|
||||||
#define _PMD_PAGE_512K 0x0004
|
#define _PMD_PAGE_512K 0x0004
|
||||||
#define _PMD_USER 0x0020 /* APG 1 */
|
#define _PMD_ACCESSED 0x0020 /* APG 1 */
|
||||||
|
#define _PMD_USER 0x0040 /* APG 2 */
|
||||||
|
|
||||||
#define _PTE_NONE_MASK 0
|
#define _PTE_NONE_MASK 0
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
struct device;
|
struct device;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
|
struct drmem_lmb;
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
|
|
||||||
@ -61,6 +62,9 @@ static inline int early_cpu_to_node(int cpu)
|
|||||||
*/
|
*/
|
||||||
return (nid < 0) ? 0 : nid;
|
return (nid < 0) ? 0 : nid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int of_drconf_to_nid_single(struct drmem_lmb *lmb);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int early_cpu_to_node(int cpu) { return 0; }
|
static inline int early_cpu_to_node(int cpu) { return 0; }
|
||||||
@ -84,10 +88,12 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NUMA */
|
static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
|
||||||
|
{
|
||||||
|
return first_online_node;
|
||||||
|
}
|
||||||
|
|
||||||
struct drmem_lmb;
|
#endif /* CONFIG_NUMA */
|
||||||
int of_drconf_to_nid_single(struct drmem_lmb *lmb);
|
|
||||||
|
|
||||||
#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
|
#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
|
||||||
extern int find_and_online_cpu_nid(int cpu);
|
extern int find_and_online_cpu_nid(int cpu);
|
||||||
|
@ -178,7 +178,7 @@ do { \
|
|||||||
* are no aliasing issues.
|
* are no aliasing issues.
|
||||||
*/
|
*/
|
||||||
#define __put_user_asm_goto(x, addr, label, op) \
|
#define __put_user_asm_goto(x, addr, label, op) \
|
||||||
asm volatile goto( \
|
asm_volatile_goto( \
|
||||||
"1: " op "%U1%X1 %0,%1 # put_user\n" \
|
"1: " op "%U1%X1 %0,%1 # put_user\n" \
|
||||||
EX_TABLE(1b, %l2) \
|
EX_TABLE(1b, %l2) \
|
||||||
: \
|
: \
|
||||||
@ -191,7 +191,7 @@ do { \
|
|||||||
__put_user_asm_goto(x, ptr, label, "std")
|
__put_user_asm_goto(x, ptr, label, "std")
|
||||||
#else /* __powerpc64__ */
|
#else /* __powerpc64__ */
|
||||||
#define __put_user_asm2_goto(x, addr, label) \
|
#define __put_user_asm2_goto(x, addr, label) \
|
||||||
asm volatile goto( \
|
asm_volatile_goto( \
|
||||||
"1: stw%X1 %0, %1\n" \
|
"1: stw%X1 %0, %1\n" \
|
||||||
"2: stw%X1 %L0, %L1\n" \
|
"2: stw%X1 %L0, %L1\n" \
|
||||||
EX_TABLE(1b, %l2) \
|
EX_TABLE(1b, %l2) \
|
||||||
|
@ -264,8 +264,9 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
|
|||||||
{
|
{
|
||||||
struct pci_io_addr_range *piar;
|
struct pci_io_addr_range *piar;
|
||||||
struct rb_node *n;
|
struct rb_node *n;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock(&pci_io_addr_cache_root.piar_lock);
|
spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
|
||||||
for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) {
|
for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) {
|
||||||
piar = rb_entry(n, struct pci_io_addr_range, rb_node);
|
piar = rb_entry(n, struct pci_io_addr_range, rb_node);
|
||||||
|
|
||||||
@ -273,7 +274,7 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v)
|
|||||||
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
|
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
|
||||||
&piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
|
&piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
|
||||||
}
|
}
|
||||||
spin_unlock(&pci_io_addr_cache_root.piar_lock);
|
spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -284,11 +284,7 @@ _ENTRY(saved_ksp_limit)
|
|||||||
|
|
||||||
rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
|
rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
|
||||||
lwz r11, 0(r11) /* Get Linux PTE */
|
lwz r11, 0(r11) /* Get Linux PTE */
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
li r9, _PAGE_PRESENT | _PAGE_ACCESSED
|
li r9, _PAGE_PRESENT | _PAGE_ACCESSED
|
||||||
#else
|
|
||||||
li r9, _PAGE_PRESENT
|
|
||||||
#endif
|
|
||||||
andc. r9, r9, r11 /* Check permission */
|
andc. r9, r9, r11 /* Check permission */
|
||||||
bne 5f
|
bne 5f
|
||||||
|
|
||||||
@ -369,11 +365,7 @@ _ENTRY(saved_ksp_limit)
|
|||||||
|
|
||||||
rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
|
rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
|
||||||
lwz r11, 0(r11) /* Get Linux PTE */
|
lwz r11, 0(r11) /* Get Linux PTE */
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
||||||
#else
|
|
||||||
li r9, _PAGE_PRESENT | _PAGE_EXEC
|
|
||||||
#endif
|
|
||||||
andc. r9, r9, r11 /* Check permission */
|
andc. r9, r9, r11 /* Check permission */
|
||||||
bne 5f
|
bne 5f
|
||||||
|
|
||||||
|
@ -202,9 +202,7 @@ SystemCall:
|
|||||||
|
|
||||||
InstructionTLBMiss:
|
InstructionTLBMiss:
|
||||||
mtspr SPRN_SPRG_SCRATCH0, r10
|
mtspr SPRN_SPRG_SCRATCH0, r10
|
||||||
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS)
|
|
||||||
mtspr SPRN_SPRG_SCRATCH1, r11
|
mtspr SPRN_SPRG_SCRATCH1, r11
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If we are faulting a kernel address, we have to use the
|
/* If we are faulting a kernel address, we have to use the
|
||||||
* kernel page tables.
|
* kernel page tables.
|
||||||
@ -224,25 +222,13 @@ InstructionTLBMiss:
|
|||||||
3:
|
3:
|
||||||
mtcr r11
|
mtcr r11
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT)
|
|
||||||
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
|
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
|
||||||
mtspr SPRN_MD_TWC, r11
|
mtspr SPRN_MD_TWC, r11
|
||||||
#else
|
|
||||||
lwz r10, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
|
|
||||||
mtspr SPRN_MI_TWC, r10 /* Set segment attributes */
|
|
||||||
mtspr SPRN_MD_TWC, r10
|
|
||||||
#endif
|
|
||||||
mfspr r10, SPRN_MD_TWC
|
mfspr r10, SPRN_MD_TWC
|
||||||
lwz r10, 0(r10) /* Get the pte */
|
lwz r10, 0(r10) /* Get the pte */
|
||||||
#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT)
|
rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED
|
||||||
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
|
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
|
||||||
mtspr SPRN_MI_TWC, r11
|
mtspr SPRN_MI_TWC, r11
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
rlwinm r11, r10, 32-5, _PAGE_PRESENT
|
|
||||||
and r11, r11, r10
|
|
||||||
rlwimi r10, r11, 0, _PAGE_PRESENT
|
|
||||||
#endif
|
|
||||||
/* The Linux PTE won't go exactly into the MMU TLB.
|
/* The Linux PTE won't go exactly into the MMU TLB.
|
||||||
* Software indicator bits 20 and 23 must be clear.
|
* Software indicator bits 20 and 23 must be clear.
|
||||||
* Software indicator bits 22, 24, 25, 26, and 27 must be
|
* Software indicator bits 22, 24, 25, 26, and 27 must be
|
||||||
@ -256,9 +242,7 @@ InstructionTLBMiss:
|
|||||||
|
|
||||||
/* Restore registers */
|
/* Restore registers */
|
||||||
0: mfspr r10, SPRN_SPRG_SCRATCH0
|
0: mfspr r10, SPRN_SPRG_SCRATCH0
|
||||||
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS)
|
|
||||||
mfspr r11, SPRN_SPRG_SCRATCH1
|
mfspr r11, SPRN_SPRG_SCRATCH1
|
||||||
#endif
|
|
||||||
rfi
|
rfi
|
||||||
patch_site 0b, patch__itlbmiss_exit_1
|
patch_site 0b, patch__itlbmiss_exit_1
|
||||||
|
|
||||||
@ -268,9 +252,7 @@ InstructionTLBMiss:
|
|||||||
addi r10, r10, 1
|
addi r10, r10, 1
|
||||||
stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
|
stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
|
||||||
mfspr r10, SPRN_SPRG_SCRATCH0
|
mfspr r10, SPRN_SPRG_SCRATCH0
|
||||||
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
|
|
||||||
mfspr r11, SPRN_SPRG_SCRATCH1
|
mfspr r11, SPRN_SPRG_SCRATCH1
|
||||||
#endif
|
|
||||||
rfi
|
rfi
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -297,30 +279,16 @@ DataStoreTLBMiss:
|
|||||||
mfspr r10, SPRN_MD_TWC
|
mfspr r10, SPRN_MD_TWC
|
||||||
lwz r10, 0(r10) /* Get the pte */
|
lwz r10, 0(r10) /* Get the pte */
|
||||||
|
|
||||||
/* Insert the Guarded flag into the TWC from the Linux PTE.
|
/* Insert Guarded and Accessed flags into the TWC from the Linux PTE.
|
||||||
* It is bit 27 of both the Linux PTE and the TWC (at least
|
* It is bit 27 of both the Linux PTE and the TWC (at least
|
||||||
* I got that right :-). It will be better when we can put
|
* I got that right :-). It will be better when we can put
|
||||||
* this into the Linux pgd/pmd and load it in the operation
|
* this into the Linux pgd/pmd and load it in the operation
|
||||||
* above.
|
* above.
|
||||||
*/
|
*/
|
||||||
rlwimi r11, r10, 0, _PAGE_GUARDED
|
rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED
|
||||||
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
|
rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K
|
||||||
mtspr SPRN_MD_TWC, r11
|
mtspr SPRN_MD_TWC, r11
|
||||||
|
|
||||||
/* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
|
|
||||||
* We also need to know if the insn is a load/store, so:
|
|
||||||
* Clear _PAGE_PRESENT and load that which will
|
|
||||||
* trap into DTLB Error with store bit set accordinly.
|
|
||||||
*/
|
|
||||||
/* PRESENT=0x1, ACCESSED=0x20
|
|
||||||
* r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
|
|
||||||
* r10 = (r10 & ~PRESENT) | r11;
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
rlwinm r11, r10, 32-5, _PAGE_PRESENT
|
|
||||||
and r11, r11, r10
|
|
||||||
rlwimi r10, r11, 0, _PAGE_PRESENT
|
|
||||||
#endif
|
|
||||||
/* The Linux PTE won't go exactly into the MMU TLB.
|
/* The Linux PTE won't go exactly into the MMU TLB.
|
||||||
* Software indicator bits 24, 25, 26, and 27 must be
|
* Software indicator bits 24, 25, 26, and 27 must be
|
||||||
* set. All other Linux PTE bits control the behavior
|
* set. All other Linux PTE bits control the behavior
|
||||||
@ -711,7 +679,7 @@ initial_mmu:
|
|||||||
li r9, 4 /* up to 4 pages of 8M */
|
li r9, 4 /* up to 4 pages of 8M */
|
||||||
mtctr r9
|
mtctr r9
|
||||||
lis r9, KERNELBASE@h /* Create vaddr for TLB */
|
lis r9, KERNELBASE@h /* Create vaddr for TLB */
|
||||||
li r10, MI_PS8MEG | MI_SVALID /* Set 8M byte page */
|
li r10, MI_PS8MEG | _PMD_ACCESSED | MI_SVALID
|
||||||
li r11, MI_BOOTINIT /* Create RPN for address 0 */
|
li r11, MI_BOOTINIT /* Create RPN for address 0 */
|
||||||
1:
|
1:
|
||||||
mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
|
mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
|
||||||
@ -775,7 +743,7 @@ _GLOBAL(mmu_pin_tlb)
|
|||||||
#ifdef CONFIG_PIN_TLB_TEXT
|
#ifdef CONFIG_PIN_TLB_TEXT
|
||||||
LOAD_REG_IMMEDIATE(r5, 28 << 8)
|
LOAD_REG_IMMEDIATE(r5, 28 << 8)
|
||||||
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
|
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
|
||||||
LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG)
|
LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
|
||||||
LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
|
LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
|
||||||
LOAD_REG_ADDR(r9, _sinittext)
|
LOAD_REG_ADDR(r9, _sinittext)
|
||||||
li r0, 4
|
li r0, 4
|
||||||
@ -797,7 +765,7 @@ _GLOBAL(mmu_pin_tlb)
|
|||||||
LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM)
|
LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM)
|
||||||
#ifdef CONFIG_PIN_TLB_DATA
|
#ifdef CONFIG_PIN_TLB_DATA
|
||||||
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
|
LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
|
||||||
LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG)
|
LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
|
||||||
#ifdef CONFIG_PIN_TLB_IMMR
|
#ifdef CONFIG_PIN_TLB_IMMR
|
||||||
li r0, 3
|
li r0, 3
|
||||||
#else
|
#else
|
||||||
@ -834,7 +802,7 @@ _GLOBAL(mmu_pin_tlb)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PIN_TLB_IMMR
|
#ifdef CONFIG_PIN_TLB_IMMR
|
||||||
LOAD_REG_IMMEDIATE(r0, VIRT_IMMR_BASE | MD_EVALID)
|
LOAD_REG_IMMEDIATE(r0, VIRT_IMMR_BASE | MD_EVALID)
|
||||||
LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED)
|
LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED | _PMD_ACCESSED)
|
||||||
mfspr r8, SPRN_IMMR
|
mfspr r8, SPRN_IMMR
|
||||||
rlwinm r8, r8, 0, 0xfff80000
|
rlwinm r8, r8, 0, 0xfff80000
|
||||||
ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \
|
ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \
|
||||||
|
@ -457,11 +457,7 @@ InstructionTLBMiss:
|
|||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
#endif
|
#endif
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
|
||||||
#else
|
|
||||||
li r1,_PAGE_PRESENT | _PAGE_EXEC
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC)
|
#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC)
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
@ -523,11 +519,7 @@ DataLoadTLBMiss:
|
|||||||
lis r1, TASK_SIZE@h /* check if kernel address */
|
lis r1, TASK_SIZE@h /* check if kernel address */
|
||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
|
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
|
||||||
#else
|
|
||||||
li r1, _PAGE_PRESENT
|
|
||||||
#endif
|
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||||
@ -603,11 +595,7 @@ DataStoreTLBMiss:
|
|||||||
lis r1, TASK_SIZE@h /* check if kernel address */
|
lis r1, TASK_SIZE@h /* check if kernel address */
|
||||||
cmplw 0,r1,r3
|
cmplw 0,r1,r3
|
||||||
mfspr r2, SPRN_SPRG_PGDIR
|
mfspr r2, SPRN_SPRG_PGDIR
|
||||||
#ifdef CONFIG_SWAP
|
|
||||||
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
|
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
|
||||||
#else
|
|
||||||
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT
|
|
||||||
#endif
|
|
||||||
bgt- 112f
|
bgt- 112f
|
||||||
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||||
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||||
|
@ -1393,13 +1393,14 @@ static void add_cpu_to_masks(int cpu)
|
|||||||
/* Activate a secondary processor. */
|
/* Activate a secondary processor. */
|
||||||
void start_secondary(void *unused)
|
void start_secondary(void *unused)
|
||||||
{
|
{
|
||||||
unsigned int cpu = smp_processor_id();
|
unsigned int cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
mmgrab(&init_mm);
|
mmgrab(&init_mm);
|
||||||
current->active_mm = &init_mm;
|
current->active_mm = &init_mm;
|
||||||
|
|
||||||
smp_store_cpu_info(cpu);
|
smp_store_cpu_info(cpu);
|
||||||
set_dec(tb_ticks_per_jiffy);
|
set_dec(tb_ticks_per_jiffy);
|
||||||
|
rcu_cpu_starting(cpu);
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
cpu_callin_map[cpu] = 1;
|
cpu_callin_map[cpu] = 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user