source: mainline/kernel/genarch/src/mm/page_ht.c@ 8ccd2ea

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

The Ultimate Solution To Illegal Virtual Aliases.
It is better to avoid them completely than to fight them.
Switch the sparc64 port to 16K pages. The TLBs and TSBs
continue to operate with 8K pages only. Page tables and
other generic parts operate with 16K pages.

Because the MMU doesn't support 16K directly, each 16K
page is emulated by a pair of 8K pages. With 16K pages,
illegal aliases cannot be created in 16K D-cache.

  • Property mode set to 100644
File size: 6.8 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 genarchmm
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Virtual Address Translation (VAT) for global page hash table.
36 */
37
38#include <genarch/mm/page_ht.h>
39#include <mm/page.h>
40#include <arch/mm/page.h>
41#include <mm/frame.h>
42#include <mm/slab.h>
43#include <mm/as.h>
44#include <arch/mm/asid.h>
45#include <arch/types.h>
46#include <arch/asm.h>
47#include <synch/spinlock.h>
48#include <arch.h>
49#include <debug.h>
50#include <memstr.h>
51#include <adt/hash_table.h>
52#include <align.h>
53
54static index_t hash(unative_t key[]);
55static bool compare(unative_t key[], count_t keys, link_t *item);
56static void remove_callback(link_t *item);
57
58static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
59 int flags);
60static void ht_mapping_remove(as_t *as, uintptr_t page);
61static pte_t *ht_mapping_find(as_t *as, uintptr_t page);
62
63/**
64 * This lock protects the page hash table. It must be acquired
65 * after address space lock and after any address space area
66 * locks.
67 */
68mutex_t page_ht_lock;
69
70/**
71 * Page hash table.
72 * The page hash table may be accessed only when page_ht_lock is held.
73 */
74hash_table_t page_ht;
75
76/** Hash table operations for page hash table. */
77hash_table_operations_t ht_operations = {
78 .hash = hash,
79 .compare = compare,
80 .remove_callback = remove_callback
81};
82
83/** Page mapping operations for page hash table architectures. */
84page_mapping_operations_t ht_mapping_operations = {
85 .mapping_insert = ht_mapping_insert,
86 .mapping_remove = ht_mapping_remove,
87 .mapping_find = ht_mapping_find
88};
89
90/** Compute page hash table index.
91 *
92 * @param key Array of two keys (i.e. page and address space).
93 *
94 * @return Index into page hash table.
95 */
96index_t hash(unative_t key[])
97{
98 as_t *as = (as_t *) key[KEY_AS];
99 uintptr_t page = (uintptr_t) key[KEY_PAGE];
100 index_t index;
101
102 /*
103 * Virtual page addresses have roughly the same probability
104 * of occurring. Least significant bits of VPN compose the
105 * hash index.
106 */
107 index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
108
109 /*
110 * Address space structures are likely to be allocated from
111 * similar addresses. Least significant bits compose the
112 * hash index.
113 */
114 index |= ((unative_t) as) & (PAGE_HT_ENTRIES - 1);
115
116 return index;
117}
118
119/** Compare page hash table item with page and/or address space.
120 *
121 * @param key Array of one or two keys (i.e. page and/or address space).
122 * @param keys Number of keys passed.
123 * @param item Item to compare the keys with.
124 *
125 * @return true on match, false otherwise.
126 */
127bool compare(unative_t key[], count_t keys, link_t *item)
128{
129 pte_t *t;
130
131 ASSERT(item);
132 ASSERT((keys > 0) && (keys <= PAGE_HT_KEYS));
133
134 /*
135 * Convert item to PTE.
136 */
137 t = hash_table_get_instance(item, pte_t, link);
138
139 if (keys == PAGE_HT_KEYS) {
140 return (key[KEY_AS] == (uintptr_t) t->as) &&
141 (key[KEY_PAGE] == t->page);
142 } else {
143 return (key[KEY_AS] == (uintptr_t) t->as);
144 }
145}
146
147/** Callback on page hash table item removal.
148 *
149 * @param item Page hash table item being removed.
150 */
151void remove_callback(link_t *item)
152{
153 pte_t *t;
154
155 ASSERT(item);
156
157 /*
158 * Convert item to PTE.
159 */
160 t = hash_table_get_instance(item, pte_t, link);
161
162 free(t);
163}
164
165/** Map page to frame using page hash table.
166 *
167 * Map virtual address page to physical address frame
168 * using flags.
169 *
170 * The page table must be locked and interrupts must be disabled.
171 *
172 * @param as Address space to which page belongs.
173 * @param page Virtual address of the page to be mapped.
174 * @param frame Physical address of memory frame to which the mapping is done.
175 * @param flags Flags to be used for mapping.
176 */
177void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
178{
179 pte_t *t;
180 unative_t key[2] = {
181 (uintptr_t) as,
182 page = ALIGN_DOWN(page, PAGE_SIZE)
183 };
184
185 if (!hash_table_find(&page_ht, key)) {
186 t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
187 ASSERT(t != NULL);
188
189 t->g = (flags & PAGE_GLOBAL) != 0;
190 t->x = (flags & PAGE_EXEC) != 0;
191 t->w = (flags & PAGE_WRITE) != 0;
192 t->k = !(flags & PAGE_USER);
193 t->c = (flags & PAGE_CACHEABLE) != 0;
194 t->p = !(flags & PAGE_NOT_PRESENT);
195
196 t->as = as;
197 t->page = ALIGN_DOWN(page, PAGE_SIZE);
198 t->frame = ALIGN_DOWN(frame, FRAME_SIZE);
199
200 hash_table_insert(&page_ht, key, &t->link);
201 }
202}
203
204/** Remove mapping of page from page hash table.
205 *
206 * Remove any mapping of page within address space as.
207 * TLB shootdown should follow in order to make effects of
208 * this call visible.
209 *
210 * The page table must be locked and interrupts must be disabled.
211 *
212 * @param as Address space to wich page belongs.
213 * @param page Virtual address of the page to be demapped.
214 */
215void ht_mapping_remove(as_t *as, uintptr_t page)
216{
217 unative_t key[2] = {
218 (uintptr_t) as,
219 page = ALIGN_DOWN(page, PAGE_SIZE)
220 };
221
222 /*
223 * Note that removed PTE's will be freed
224 * by remove_callback().
225 */
226 hash_table_remove(&page_ht, key, 2);
227}
228
229
230/** Find mapping for virtual page in page hash table.
231 *
232 * Find mapping for virtual page.
233 *
234 * The page table must be locked and interrupts must be disabled.
235 *
236 * @param as Address space to wich page belongs.
237 * @param page Virtual page.
238 *
239 * @return NULL if there is no such mapping; requested mapping otherwise.
240 */
241pte_t *ht_mapping_find(as_t *as, uintptr_t page)
242{
243 link_t *hlp;
244 pte_t *t = NULL;
245 unative_t key[2] = {
246 (uintptr_t) as,
247 page = ALIGN_DOWN(page, PAGE_SIZE)
248 };
249
250 hlp = hash_table_find(&page_ht, key);
251 if (hlp)
252 t = hash_table_get_instance(hlp, pte_t, link);
253
254 return t;
255}
256
257/** @}
258 */
Note: See TracBrowser for help on using the repository browser.