source: mainline/kernel/arch/sparc64/include/trap/mmu.h@ 1c6b3a2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1c6b3a2 was 36f19c0, checked in by Jakub Jermar <jakub@…>, 18 years ago

Fix a nasty bug in the TLB miss handlers on sparc64.
After we no longer lock the kernel stack in the DTLB,
there is a real danger of nested DTLB misses. The nested
miss can very easily clobber the DTLB Tag Access register.
Therefore, the original miss may not read this register, but
it has to receive its value as an argument. The argument
value is saved in the trap table when it is guaranteed that
the nested TLB miss will not occur.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup sparc64interrupt
30 * @{
31 */
32/**
33 * @file
34 * @brief This file contains fast MMU trap handlers.
35 */
36
37#ifndef KERN_sparc64_MMU_TRAP_H_
38#define KERN_sparc64_MMU_TRAP_H_
39
40#include <arch/stack.h>
41#include <arch/regdef.h>
42#include <arch/mm/tlb.h>
43#include <arch/mm/mmu.h>
44#include <arch/mm/tte.h>
45#include <arch/trap/regwin.h>
46
47#ifdef CONFIG_TSB
48#include <arch/mm/tsb.h>
49#endif
50
51#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS 0x64
52#define TT_FAST_DATA_ACCESS_MMU_MISS 0x68
53#define TT_FAST_DATA_ACCESS_PROTECTION 0x6c
54
55#define FAST_MMU_HANDLER_SIZE 128
56
57#ifdef __ASM__
58
59.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
60 /*
61 * First, try to refill TLB from TSB.
62 */
63#ifdef CONFIG_TSB
64 ldxa [%g0] ASI_IMMU, %g1 ! read TSB Tag Target Register
65 ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2 ! read TSB 8K Pointer
66 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5
67 cmp %g1, %g4 ! is this the entry we are looking for?
68 bne,pn %xcc, 0f
69 nop
70 stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG ! copy mapping from ITSB to ITLB
71 retry
72#endif
73
740:
75 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
76 PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
77.endm
78
79.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
80 /*
81 * First, try to refill TLB from TSB.
82 */
83
84#ifdef CONFIG_TSB
85 ldxa [%g0] ASI_DMMU, %g1 ! read TSB Tag Target Register
86 srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2 ! is this a kernel miss?
87 brz,pn %g2, 0f
88 ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3 ! read TSB 8K Pointer
89 ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5
90 cmp %g1, %g4 ! is this the entry we are looking for?
91 bne,pn %xcc, 0f
92 nop
93 stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG ! copy mapping from DTSB to DTLB
94 retry
95#endif
96
97 /*
98 * Second, test if it is the portion of the kernel address space
99 * which is faulting. If that is the case, immediately create
100 * identity mapping for that page in DTLB. VPN 0 is excluded from
101 * this treatment.
102 *
103 * Note that branch-delay slots are used in order to save space.
104 */
1050:
106 mov VA_DMMU_TAG_ACCESS, %g1
107 ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN
108 set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
109 andcc %g1, %g2, %g3 ! get Context
110 bnz 0f ! Context is non-zero
111 andncc %g1, %g2, %g3 ! get page address into %g3
112 bz 0f ! page address is zero
113
114 sethi %hi(kernel_8k_tlb_data_template), %g2
115 ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2
116 or %g3, %g2, %g2
117 stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page
118 retry
119
120 /*
121 * Third, catch and handle special cases when the trap is caused by
122 * the userspace register window spill or fill handler. In case
123 * one of these two traps caused this trap, we just lower the trap
124 * level and service the DTLB miss. In the end, we restart
125 * the offending SAVE or RESTORE.
126 */
1270:
128.if (\tl > 0)
129 wrpr %g0, 1, %tl
130.endif
131
132 /*
133 * Switch from the MM globals.
134 */
135 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
136
137 /*
138 * Read the Tag Access register for the higher-level handler.
139 * This is necessary to survive nested DTLB misses.
140 */
141 mov VA_DMMU_TAG_ACCESS, %g2
142 ldxa [%g2] ASI_DMMU, %g2
143
144 /*
145 * g2 will be passed as an argument to fast_data_access_mmu_miss().
146 */
147 PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
148.endm
149
150.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
151 /*
152 * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
153 */
154
155.if (\tl > 0)
156 wrpr %g0, 1, %tl
157.endif
158
159 /*
160 * Switch from the MM globals.
161 */
162 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
163
164 /*
165 * Read the Tag Access register for the higher-level handler.
166 * This is necessary to survive nested DTLB misses.
167 */
168 mov VA_DMMU_TAG_ACCESS, %g2
169 ldxa [%g2] ASI_DMMU, %g2
170
171 /*
172 * g2 will be passed as an argument to fast_data_access_mmu_miss().
173 */
174 PREEMPTIBLE_HANDLER fast_data_access_protection
175.endm
176
177#endif /* __ASM__ */
178
179#endif
180
181/** @}
182 */
Note: See TracBrowser for help on using the repository browser.