Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


correct XTEST behavior in RTM code
[palacios.git] / palacios / include / extensions / trans_mem.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2012, NWU EECS 441 Transactional Memory Team
11  * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Maciek Swiech <dotpyfe@u.northwestern.edu>
15  *          Marcel Flores <marcel-flores@u.northwestern.edu>
16  *          Zachary Bischof <zbischof@u.northwestern.edu>
17  *          Kyle C. Hale <kh@u.northwestern.edu>
18  *
19  * This is free software.  You are permitted to use,
20  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21  *
22  
23 RTM Implementation Wishlist (roughly in order of priority)
24 Kyle Hale, Maciek Swiech 2014
25
26 From Intel Architecture Instruction Set Extensions Programming Reference, Section 8.3, p.8-6
27 link: http://software.intel.com/sites/default/files/m/9/2/3/41604
28
29 - architectural registers need to be saved / restored 
30 - abort on interrupts, asynchronous events
31 - abort on CPUID, PAUSE
32 - abort on non-writeback memory ops, including ifetches to uncacheable mem
33 - RTM-debugger support
34 - RTM nesting
35 - parameterized cache model, for generating hardware configuration-based aborts
36
37 - to be able to model specific implementations, add options (runtime or compiletime) to abort on:
38     * x86/mmx state changes, (also fxstor, fxsave),
39     * cli, sti, popfd, popfq, clts
40     * mov to segment regs, pop segment regs, lds, les, lfs, lgs, lss, swapgs, wrfsbase, wrgsbase, lgdt, sgdt, lidt, sidt, lldt, sldt, ltr, 
41       str, far call, far jmp, far ret, far iret, mov to DRx, mov to cr0-4, cr8 lmsw
42     * sysenter, syscall, sysexit, sysret
43     * clflush, invd, wbinvd, invlpg, invpcid
44     * memory instructions with temporal hints (e.g. movntdqa)
45     * xsave, xsaveopt, xrstor
46     * interrupts: INTn, INTO
47     * IO: in, ins, rep ins, out, outs, rep outs, and variants
48     * VMX instructions
49     * smx: getsec
50     * ud2, rsm, rdmsr, wrmsr, hlt, monitor, mwait, xsetbv, vzeroupper, maskmovq, v/maskmovdqu
51     
52  *
53  *
54  * We claim that we can have a single, shared "cache"-like box
55  * that handles all writes and reads when TM is on on any core.  The
56  * idea is that if TM is on on any core, we redirect reads/writes
57  * that we get to the box, and it records them internally for 
58  * future playback, and tells us whether an abort condition has
59  * occured or not:
60  *
61  * error = handle_start_tx(boxstate,vcorenum);
62  * error = handle_abort(boxstate,vcorenum);
63  * error = handle_commit(boxstate,vcorenum);
64  *
65  * should_abort = handle_write(boxstate, vcorenum, physaddr, data, datalen);
66  * should_abort = handle_read(boxstate, vcorenum,physaddr, *data, datalen);
67  *
68  * One implementation:
69  *
70  * struct rec {
71  *    enum {READ,WRITE,BEGIN,ABORT,END} op;
72  *    addr_t vcorenum,
73  *           physaddr,
74  *           datalen ;
75  *    struct rec *next;
76  * }
77  *
78  * struct cache_model {
79  *    void *init(xml spec);  // make a cache, return ptr to state
80  *    int write(void *priv, physaddr, datalen, int (*change_cb(int core,
81  *                             physaddrstart, len));
82  *    // similiar for read
83  *
84  * // Idea is that we pass writes to cache model, it calls us back to say which
85  * lines on which cores have changed
86  * }
87  *
88  *
89  * struct boxstate {
90  *    struct cache_model *model; //
91  *    lock_t     global_lock; // any handle_* func acquires this first
92  *    uint64_t   loglen;
93  *    uint64_t   numtransactionsactive;
94  *    struct rec *first;
95  * }
96  *
97  * int handle_write(box,vcore,physaddr,data,datalen) {
98  *
99  */
100
101 #ifndef __TRANS_MEM_H__
102 #define __TRANS_MEM_H__
103
104 #include <palacios/vmm_lock.h>
105 #include <palacios/vmcb.h>
106 #include <palacios/vmm_paging.h>
107
108 #define MAX_CORES 32
109
110 #define TM_KICKBACK_CALL 0x1337
111
112 #define HTABLE_SEARCH(h, k) ({ addr_t ret; v3_lock(h##_lock); ret = v3_htable_search((h), (k)); v3_unlock(h##_lock); ret; })
113 #define HTABLE_INSERT(h, k, v) ({ addr_t ret; v3_lock(h##_lock); ret = v3_htable_insert((h), (k), (addr_t)(v)); v3_unlock(h##_lock); ret; })
114
115 #define INSTR_INJECT_LEN 10
116 #define INSTR_BUF_SZ  15
117 #define ERR_STORE_MUST_ABORT -2
118 #define ERR_STORE_FAIL -1
119 #define ERR_DECODE_FAIL -1
120 #define ERR_TRANS_FAULT_FAIL 0
121 #define TRANS_FAULT_OK 1
122 #define TRANS_HCALL_FAIL -1 
123 #define TRANS_HCALL_OK 0
124
125 /* conflict checking codes */
126 #define ERR_CHECK_FAIL -1
127 #define CHECK_MUST_ABORT -2
128 #define CHECK_IS_CONFLICT 1
129 #define CHECK_NO_CONFLICT 0
130
131 /* RTM instruction handling */
132 #define XBEGIN_INSTR_LEN 0x6
133 #define XEND_INSTR_LEN   0x3
134 #define XABORT_INSTR_LEN 0x3
135 #define XTEST_INSTR_LEN  0x3
136
137 /* abort status definitions (these are bit indeces) */
138 #define ABORT_XABORT     0x0 // xabort instr
139 #define ABORT_RETRY      0x1 // may succeed on retry (must be clear if bit 0 set)
140 #define ABORT_CONFLICT   0x2 // another process accessed memory in the transaction
141 #define ABORT_OFLOW      0x3 // internal buffer overflowed
142 #define ABORT_BKPT       0x4 // debug breakpoint was hit
143 #define ABORT_NESTED     0x5 // abort occured during nested transaction (not currently used)
144
145
146 typedef enum tm_abrt_cause {
147     TM_ABORT_XABORT,
148     TM_ABORT_CONFLICT,
149     TM_ABORT_INTERNAL,
150     TM_ABORT_BKPT,
151     TM_ABORT_UNSPECIFIED,
152 } tm_abrt_cause_t;
153
154 struct v3_tm_access_type {
155     uint8_t r : 1;
156     uint8_t w : 1;
157 } __attribute__((packed));
158
159 struct v3_ctxt_tuple {
160     void * gva;
161     void * core_id;
162     void * core_lt;
163 } __attribute__((packed));
164
165 /* 441-tm: Are we currently in a transaction */
166 enum TM_MODE_E { 
167     TM_OFF = 0, 
168     TM_ON = 1,
169 };
170
171 /* 441-tm: Current state of the transaction state machine */
172 enum TM_STATE_E {
173     TM_NULL = 0,
174     TM_IFETCH = 1,
175     TM_EXEC = 2
176 //    TM_ABORT = 3
177 };
178
179 typedef enum v3_tm_op {
180     OP_TYPE_READ,
181     OP_TYPE_WRITE
182 } v3_tm_op_t;
183
184 struct v3_trans_mem {
185     /* current transaction */
186     uint64_t t_num;
187
188     /* 441-tm: linked list to store core's reads and writes */
189     struct list_head trans_r_list;
190     struct list_head trans_w_list;
191
192     /* 441-tm: hash tables of addresses */
193     struct hashtable * addr_ctxt;       // records the core transaction context at time of address use
194     v3_lock_t addr_ctxt_lock;
195     uint64_t addr_ctxt_entries;
196
197     struct hashtable * access_type;     // hashes addr:corenum:t_num for each address use
198     v3_lock_t access_type_lock;
199     uint64_t access_type_entries;
200
201     /* 441-tm: lets remember things about the next instruction */
202     uint8_t dirty_instr_flag;
203     addr_t  dirty_hva;
204     addr_t  dirty_gva;
205     uchar_t dirty_instr[15];
206     int     cur_instr_len;
207
208     enum TM_MODE_E TM_MODE;
209     enum TM_STATE_E TM_STATE;
210     uint64_t TM_ABORT;
211
212     struct shadow_page_data * staging_page;
213
214     /* 441-tm: Remember the failsafe addr */
215     addr_t  fail_call;
216
217     /* 441-tm: Save the rax we are about to ruin */
218     v3_reg_t clobbered_rax;
219
220     // branching instrs
221     int to_branch;
222     addr_t offset;
223
224     // timing info
225     uint64_t entry_time;
226     uint64_t exit_time;
227     uint64_t entry_exits;
228
229     // cache box
230     struct cache_box * box;
231
232     struct guest_info * ginfo;
233
234 };
235
236
237 struct v3_tm_state {
238     v3_lock_t lock;
239     enum TM_MODE_E TM_MODE;
240     uint64_t cores_active;
241
242     uint64_t  * last_trans;
243 };
244
245 struct hash_chain {
246     uint64_t * curr_lt;
247
248     struct list_head lt_node;
249 };
250
251 // called from #PF handler, stages entries, catches reads / writes
252 addr_t v3_handle_trans_mem_fault(struct guest_info *core, 
253                                  addr_t fault_addr, 
254                                  pf_error_t error);
255
256 // restores instruction after core->rip
257 int v3_restore_dirty_instr(struct guest_info *core);
258
259 // restores instruction after core->rip
260 int v3_restore_abort_instr(struct guest_info *core);
261
262 // handles abort cleanup, called from INT/EXCP or XABORT
263 int v3_handle_trans_abort(struct guest_info *core,
264                          tm_abrt_cause_t cause,
265                          uint8_t xabort_reason);
266
267 // record a memory access in hashes
268 int tm_record_access (struct v3_trans_mem * tm, 
269                       uint8_t write, 
270                       addr_t gva);
271
272 // garbage collect hash recordings
273 int tm_hash_gc (struct v3_trans_mem * tm);
274
275 // check address for conflicts
276 int tm_check_conflict(struct   v3_vm_info * vm_info,
277                       addr_t   gva,
278                       v3_tm_op_t op_type,
279                       uint64_t core_num, 
280                       uint64_t curr_ctxt);
281
282 // increment transaction number
283 int v3_tm_inc_tnum(struct v3_trans_mem * tm);
284
285
286 /* exception-related functions */
287 int v3_tm_handle_exception(struct guest_info * info, addr_t exit_code);
288
289 void v3_tm_set_excp_intercepts(vmcb_ctrl_t * ctrl_area);
290
291 void v3_tm_check_intr_state(struct guest_info * info, 
292         vmcb_ctrl_t * guest_ctrl, 
293         vmcb_saved_state_t * guest_state);
294
295
296 /* paging-related functions */
297 int v3_tm_handle_pf_64 (struct guest_info * info,
298                         pf_error_t error_code,
299                         addr_t fault_addr,
300                         addr_t * page_to_use);
301
302 void v3_tm_handle_usr_tlb_miss(struct guest_info * info,
303                                pf_error_t error_code,
304                                addr_t page_to_use,
305                                addr_t * shadow_pa);
306
307 void v3_tm_handle_read_fault(struct guest_info * info,
308                              pf_error_t error_code,
309                              pte64_t * shadow_pte);
310
311 #include <palacios/vmm_decoder.h>
312
313 /* decoding-related functions */
314 int v3_tm_decode_rtm_instrs(struct guest_info * info, 
315                             addr_t instr_ptr, 
316                             struct x86_instr * instr);
317
318
319 #endif