ia64/xen-unstable

view xen/include/asm-ia64/vmmu.h @ 10938:bfc69471550e

[IA64] fix a fetch code bug

Fetch code may fail, if there is no corresponding tlb entry
in THASH-VTLB. This patch adds "retry mechanism" to resolve
this issue.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@xenbuild.aw
date Wed Aug 09 08:01:52 2006 -0600 (2006-08-09)
parents 561df7d9cecc
children 9e9d8696fb55
line source
2 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
3 /*
4 * vmmu.h: virtual memory management unit related APIs and data structure.
5 * Copyright (c) 2004, Intel Corporation.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 *
20 * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com)
21 */
23 #ifndef XEN_TLBthash_H
24 #define XEN_TLBthash_H
26 #define MAX_CCN_DEPTH (15) // collision chain depth
27 #define VCPU_VTLB_SHIFT (20) // 1M for VTLB
28 #define VCPU_VTLB_SIZE (1UL<<VCPU_VTLB_SHIFT)
29 #define VCPU_VTLB_ORDER (VCPU_VTLB_SHIFT - PAGE_SHIFT)
30 #define VCPU_VHPT_SHIFT (24) // 16M for VTLB
31 #define VCPU_VHPT_SIZE (1UL<<VCPU_VHPT_SHIFT)
32 #define VCPU_VHPT_ORDER (VCPU_VHPT_SHIFT - PAGE_SHIFT)
33 #define VTLB(v,_x) (v->arch.vtlb._x)
34 #define VHPT(v,_x) (v->arch.vhpt._x)
35 #ifndef __ASSEMBLY__
37 #include <xen/config.h>
38 #include <xen/types.h>
39 #include <public/xen.h>
40 #include <asm/tlb.h>
41 #include <asm/regionreg.h>
42 #include <asm/vmx_mm_def.h>
43 #include <asm/bundle.h>
44 //#define THASH_TLB_TR 0
45 //#define THASH_TLB_TC 1
48 // bit definition of TR, TC search cmobination
49 //#define THASH_SECTION_TR (1<<0)
50 //#define THASH_SECTION_TC (1<<1)
52 /*
53 * Next bit definition must be same with THASH_TLB_XX
54 #define PTA_BASE_SHIFT (15)
55 */
60 #define HIGH_32BITS(x) bits(x,32,63)
61 #define LOW_32BITS(x) bits(x,0,31)
63 typedef union search_section {
64 struct {
65 u32 tr : 1;
66 u32 tc : 1;
67 u32 rsv: 30;
68 };
69 u32 v;
70 } search_section_t;
73 enum {
74 ISIDE_TLB=0,
75 DSIDE_TLB=1
76 };
77 #define VTLB_PTE_P_BIT 0
78 #define VTLB_PTE_IO_BIT 60
79 #define VTLB_PTE_IO (1UL<<VTLB_PTE_IO_BIT)
80 #define VTLB_PTE_P (1UL<<VTLB_PTE_P_BIT)
81 typedef struct thash_data {
82 union {
83 struct {
84 u64 p : 1; // 0
85 u64 rv1 : 1; // 1
86 u64 ma : 3; // 2-4
87 u64 a : 1; // 5
88 u64 d : 1; // 6
89 u64 pl : 2; // 7-8
90 u64 ar : 3; // 9-11
91 u64 ppn : 38; // 12-49
92 u64 rv2 : 2; // 50-51
93 u64 ed : 1; // 52
94 u64 ig1 : 3; // 53-63
95 };
96 struct {
97 u64 __rv1 : 53; // 0-52
98 u64 contiguous : 1; //53
99 u64 tc : 1; // 54 TR or TC
100 u64 cl : 1; // 55 I side or D side cache line
101 u64 len : 4; // 56-59
102 u64 io : 1; // 60 entry is for io or not
103 u64 nomap : 1; // 61 entry cann't be inserted into machine TLB.
104 u64 checked : 1; // 62 for VTLB/VHPT sanity check
105 u64 invalid : 1; // 63 invalid entry
106 };
107 u64 page_flags;
108 }; // same for VHPT and TLB
110 union {
111 struct {
112 u64 rv3 : 2; // 0-1
113 u64 ps : 6; // 2-7
114 u64 key : 24; // 8-31
115 u64 rv4 : 32; // 32-63
116 };
117 u64 itir;
118 };
119 union {
120 struct { // For TLB
121 u64 ig2 : 12; // 0-11
122 u64 vpn : 49; // 12-60
123 u64 vrn : 3; // 61-63
124 };
125 u64 vadr;
126 u64 ifa;
127 struct { // For VHPT
128 u64 tag : 63; // 0-62
129 u64 ti : 1; // 63, invalid entry for VHPT
130 };
131 u64 etag; // extended tag for VHPT
132 };
133 union {
134 struct thash_data *next;
135 u64 rid; // only used in guest TR
136 // u64 tr_idx;
137 };
138 } thash_data_t;
140 #define INVALIDATE_VHPT_HEADER(hdata) \
141 { ((hdata)->page_flags)=0; \
142 ((hdata)->itir)=PAGE_SHIFT<<2; \
143 ((hdata)->etag)=1UL<<63; \
144 ((hdata)->next)=0;}
146 #define INVALIDATE_TLB_HEADER(hash) INVALIDATE_VHPT_HEADER(hash)
148 #define INVALIDATE_HASH_HEADER(hcb,hash) INVALIDATE_VHPT_HEADER(hash)
150 #define INVALID_VHPT(hdata) ((hdata)->ti)
151 #define INVALID_TLB(hdata) ((hdata)->ti)
152 #define INVALID_TR(hdata) (!(hdata)->p)
153 #define INVALID_ENTRY(hcb, hdata) INVALID_VHPT(hdata)
156 /*
157 * Architecture ppn is in 4KB unit while XEN
158 * page may be different(1<<PAGE_SHIFT).
159 */
160 static inline u64 arch_to_xen_ppn(u64 appn)
161 {
162 return (appn >>(PAGE_SHIFT-ARCH_PAGE_SHIFT));
163 }
165 static inline u64 xen_to_arch_ppn(u64 xppn)
166 {
167 return (xppn <<(PAGE_SHIFT- ARCH_PAGE_SHIFT));
168 }
170 typedef enum {
171 THASH_TLB=0,
172 THASH_VHPT
173 } THASH_TYPE;
175 struct thash_cb;
176 /*
177 * Use to calculate the HASH index of thash_data_t.
178 */
179 typedef u64 *(THASH_FN)(PTA pta, u64 va);
180 typedef u64 *(TTAG_FN)(PTA pta, u64 va);
181 typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages);
182 typedef void *(REM_NOTIFIER_FN)(struct thash_cb *hcb, thash_data_t *entry);
183 typedef void (RECYCLE_FN)(struct thash_cb *hc, u64 para);
184 typedef ia64_rr (GET_RR_FN)(struct vcpu *vcpu, u64 reg);
185 typedef thash_data_t *(FIND_OVERLAP_FN)(struct thash_cb *hcb,
186 u64 va, u64 ps, int rid, char cl, search_section_t s_sect);
187 typedef thash_data_t *(FIND_NEXT_OVL_FN)(struct thash_cb *hcb);
188 typedef void (REM_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry);
189 typedef void (INS_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry, u64 va);
192 typedef struct thash_cb {
193 /* THASH base information */
194 thash_data_t *hash; // hash table pointer, aligned at thash_sz.
195 u64 hash_sz; // size of above data.
196 void *cch_buf; // base address of collision chain.
197 u64 cch_sz; // size of above data.
198 thash_data_t *cch_freelist;
199 thash_data_t *cch_rec_head; // cch recycle header
200 PTA pta;
201 } thash_cb_t;
203 /*
204 * Initialize internal control data before service.
205 */
206 extern void thash_init(thash_cb_t *hcb, u64 sz);
208 /*
209 * Insert an entry to hash table.
210 * NOTES:
211 * 1: TLB entry may be TR, TC or Foreign Map. For TR entry,
212 * itr[]/dtr[] need to be updated too.
213 * 2: Inserting to collision chain may trigger recycling if
214 * the buffer for collision chain is empty.
215 * 3: The new entry is inserted at the hash table.
216 * (I.e. head of the collision chain)
217 * 4: Return the entry in hash table or collision chain.
218 *
219 */
220 //extern void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
221 //extern void thash_tr_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va, int idx);
222 extern int vtr_find_overlap(struct vcpu *vcpu, u64 va, u64 ps, int is_data);
223 extern u64 get_mfn(struct domain *d, u64 gpfn);
224 /*
225 * Force to delete a found entry no matter TR or foreign map for TLB.
226 * NOTES:
227 * 1: TLB entry may be TR, TC or Foreign Map. For TR entry,
228 * itr[]/dtr[] need to be updated too.
229 * 2: This API must be called after thash_find_overlap() or
230 * thash_find_next_overlap().
231 * 3: Return TRUE or FALSE
232 *
233 */
234 extern void thash_remove(thash_cb_t *hcb, thash_data_t *entry);
235 extern void thash_tr_remove(thash_cb_t *hcb, thash_data_t *entry/*, int idx*/);
237 /*
238 * Find an overlap entry in hash table and its collision chain.
239 * Refer to SDM2 4.1.1.4 for overlap definition.
240 * PARAS:
241 * 1: in: TLB format entry, rid:ps must be same with vrr[].
242 * va & ps identify the address space for overlap lookup
243 * 2: section can be combination of TR, TC and FM. (THASH_SECTION_XX)
244 * 3: cl means I side or D side.
245 * RETURNS:
246 * NULL to indicate the end of findings.
247 * NOTES:
248 *
249 */
250 extern thash_data_t *thash_find_overlap(thash_cb_t *hcb,
251 thash_data_t *in, search_section_t s_sect);
252 extern thash_data_t *thash_find_overlap_ex(thash_cb_t *hcb,
253 u64 va, u64 ps, int rid, char cl, search_section_t s_sect);
256 /*
257 * Similar with thash_find_overlap but find next entry.
258 * NOTES:
259 * Intermediate position information is stored in hcb->priv.
260 */
261 extern thash_data_t *thash_find_next_overlap(thash_cb_t *hcb);
263 /*
264 * Find and purge overlap entries in hash table and its collision chain.
265 * PARAS:
266 * 1: in: TLB format entry, rid:ps must be same with vrr[].
267 * rid, va & ps identify the address space for purge
268 * 2: section can be combination of TR, TC and FM. (thash_SECTION_XX)
269 * 3: cl means I side or D side.
270 * NOTES:
271 *
272 */
273 extern void thash_purge_entries(struct vcpu *v, u64 va, u64 ps);
274 extern void thash_purge_and_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa, int type);
276 /*
277 * Purge all TCs or VHPT entries including those in Hash table.
278 *
279 */
280 extern void thash_purge_all(struct vcpu *v);
282 /*
283 * Lookup the hash table and its collision chain to find an entry
284 * covering this address rid:va.
285 *
286 */
287 extern thash_data_t *vtlb_lookup(struct vcpu *v,u64 va,int is_data);
288 extern int thash_lock_tc(thash_cb_t *hcb, u64 va, u64 size, int rid, char cl, int lock);
291 #define ITIR_RV_MASK (((1UL<<32)-1)<<32 | 0x3)
292 #define PAGE_FLAGS_RV_MASK (0x2 | (0x3UL<<50)|(((1UL<<11)-1)<<53))
293 extern u64 machine_ttag(PTA pta, u64 va);
294 extern u64 machine_thash(PTA pta, u64 va);
295 extern void purge_machine_tc_by_domid(domid_t domid);
296 extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb);
297 extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va);
298 extern void init_domain_tlb(struct vcpu *d);
299 extern void free_domain_tlb(struct vcpu *v);
300 extern thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag);
301 extern thash_data_t * vhpt_lookup(u64 va);
302 extern void machine_tlb_purge(u64 va, u64 ps);
303 extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle);
304 extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma);
305 extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
306 extern void vtlb_insert(struct vcpu *vcpu, u64 pte, u64 itir, u64 va);
307 extern u64 translate_phy_pte(struct vcpu *v, u64 *pte, u64 itir, u64 va);
308 extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa);
309 extern u64 guest_vhpt_lookup(u64 iha, u64 *pte);
311 static inline void vmx_vcpu_set_tr (thash_data_t *trp, u64 pte, u64 itir, u64 va, u64 rid)
312 {
313 trp->page_flags = pte;
314 trp->itir = itir;
315 trp->vadr = va;
316 trp->rid = rid;
317 }
319 #endif /* __ASSEMBLY__ */
321 #endif /* XEN_TLBthash_H */