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.


68a1636d738ac3737b5db66615195326bd77d87b
[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 - on XABORT / abort RAX needs to be set with the reason
30 - architectural registers need to be saved / restored 
31 - exceptions that misuse of TSX instructions can raise
32 - abort on interrupts, asynchronous events
33 - abort on CPUID, PAUSE
34 - abort on non-writeback memory ops, including ifetches to uncacheable mem
35 - RTM-debugger support
36 - RTM nesting
37 - parameterized cache model, for generating hardware configuration-based aborts
38
39 - to be able to model specific implementations, add options (runtime or compiletime) to abort on:
40     * x86/mmx state changes, (also fxstor, fxsave),
41     * cli, sti, popfd, popfq, clts
42     * mov to segment regs, pop segment regs, lds, les, lfs, lgs, lss, swapgs, wrfsbase, wrgsbase, lgdt, sgdt, lidt, sidt, lldt, sldt, ltr, 
43       str, far call, far jmp, far ret, far iret, mov to DRx, mov to cr0-4, cr8 lmsw
44     * sysenter, syscall, sysexit, sysret
45     * clflush, invd, wbinvd, invlpg, invpcid
46     * memory instructions with temporal hints (e.g. movntdqa)
47     * xsave, xsaveopt, xrstor
48     * interrupts: INTn, INTO
49     * IO: in, ins, rep ins, out, outs, rep outs, and variants
50     * VMX instructions
51     * smx: getsec
52     * ud2, rsm, rdmsr, wrmsr, hlt, monitor, mwait, xsetbv, vzeroupper, maskmovq, v/maskmovdqu
53     
54  *
55  *
56  * We claim that we can have a single, shared "cache"-like box
57  * that handles all writes and reads when TM is on on any core.  The
58  * idea is that if TM is on on any core, we redirect reads/writes
59  * that we get to the box, and it records them internally for 
60  * future playback, and tells us whether an abort condition has
61  * occured or not:
62  *
63  * error = handle_start_tx(boxstate,vcorenum);
64  * error = handle_abort(boxstate,vcorenum);
65  * error = handle_commit(boxstate,vcorenum);
66  *
67  * should_abort = handle_write(boxstate, vcorenum, physaddr, data, datalen);
68  * should_abort = handle_read(boxstate, vcorenum,physaddr, *data, datalen);
69  *
70  * One implementation:
71  *
72  * struct rec {
73  *    enum {READ,WRITE,BEGIN,ABORT,END} op;
74  *    addr_t vcorenum,
75  *           physaddr,
76  *           datalen ;
77  *    struct rec *next;
78  * }
79  *
80  * struct cache_model {
81  *    void *init(xml spec);  // make a cache, return ptr to state
82  *    int write(void *priv, physaddr, datalen, int (*change_cb(int core,
83  *                             physaddrstart, len));
84  *    // similiar for read
85  *
86  * // Idea is that we pass writes to cache model, it calls us back to say which
87  * lines on which cores have changed
88  * }
89  *
90  *
91  * struct boxstate {
92  *    struct cache_model *model; //
93  *    lock_t     global_lock; // any handle_* func acquires this first
94  *    uint64_t   loglen;
95  *    uint64_t   numtransactionsactive;
96  *    struct rec *first;
97  * }
98  *
99  * int handle_write(box,vcore,physaddr,data,datalen) {
100  *
101  */
102
103 #ifndef __TRANS_MEM_H__
104 #define __TRANS_MEM_H__
105
106 #include <palacios/vmm_lock.h>
107 #include <palacios/vmcb.h>
108 #include <palacios/vmm_paging.h>
109
110 #define MAX_CORES 32
111
112 #define TM_KICKBACK_CALL 0x1337
113
114 #define HTABLE_SEARCH(h, k) ({ addr_t ret; v3_lock(h##_lock); ret = v3_htable_search((h), (k)); v3_unlock(h##_lock); ret; })
115 #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; })
116
117 #define INSTR_INJECT_LEN 10
118 #define INSTR_BUF_SZ  15
119 #define ERR_STORE_MUST_ABORT -2
120 #define ERR_STORE_FAIL -1
121 #define ERR_DECODE_FAIL -1
122 #define ERR_TRANS_FAULT_FAIL 0
123 #define TRANS_FAULT_OK 1
124 #define TRANS_HCALL_FAIL -1 
125 #define TRANS_HCALL_OK 0
126
127 /* conflict checking codes */
128 #define ERR_CHECK_FAIL -1
129 #define CHECK_MUST_ABORT -2
130 #define CHECK_IS_CONFLICT 1
131 #define CHECK_NO_CONFLICT 0
132
133 /* RTM instruction handling */
134 #define XBEGIN_INSTR_LEN 0x6
135 #define XEND_INSTR_LEN   0x3
136 #define XABORT_INSTR_LEN 0x3
137 #define XTEST_INSTR_LEN  0x3
138
139
140 struct v3_tm_access_type {
141     uint8_t r : 1;
142     uint8_t w : 1;
143 } __attribute__((packed));
144
145 struct v3_ctxt_tuple {
146     void * gva;
147     void * core_id;
148     void * core_lt;
149 } __attribute__((packed));
150
151 /* 441-tm: Are we currently in a transaction */
152 enum TM_MODE_E { 
153     TM_OFF = 0, 
154     TM_ON = 1,
155 };
156
157 /* 441-tm: Current state of the transaction state machine */
158 enum TM_STATE_E {
159     TM_NULL = 0,
160     TM_IFETCH = 1,
161     TM_EXEC = 2
162 //    TM_ABORT = 3
163 };
164
165 typedef enum v3_tm_op {
166     OP_TYPE_READ,
167     OP_TYPE_WRITE
168 } v3_tm_op_t;
169
170 struct v3_trans_mem {
171     /* current transaction */
172     uint64_t t_num;
173
174     /* 441-tm: linked list to store core's reads and writes */
175     struct list_head trans_r_list;
176     struct list_head trans_w_list;
177
178     /* 441-tm: hash tables of addresses */
179     struct hashtable * addr_ctxt;       // records the core transaction context at time of address use
180     v3_lock_t addr_ctxt_lock;
181     uint64_t addr_ctxt_entries;
182
183     struct hashtable * access_type;     // hashes addr:corenum:t_num for each address use
184     v3_lock_t access_type_lock;
185     uint64_t access_type_entries;
186
187     /* 441-tm: lets remember things about the next instruction */
188     uint8_t dirty_instr_flag;
189     addr_t  dirty_hva;
190     addr_t  dirty_gva;
191     uchar_t dirty_instr[15];
192     int     cur_instr_len;
193
194     enum TM_MODE_E TM_MODE;
195     enum TM_STATE_E TM_STATE;
196     uint64_t TM_ABORT;
197
198     struct shadow_page_data * staging_page;
199
200     /* 441-tm: Remember the failsafe addr */
201     addr_t  fail_call;
202
203     /* 441-tm: Save the rax we are about to ruin */
204     v3_reg_t clobbered_rax;
205
206     // branching instrs
207     int to_branch;
208     addr_t offset;
209
210     // timing info
211     uint64_t entry_time;
212     uint64_t exit_time;
213     uint64_t entry_exits;
214
215     // cache box
216     struct cache_box * box;
217
218     struct guest_info * ginfo;
219
220 };
221
222
223 struct v3_tm_state {
224     v3_lock_t lock;
225     enum TM_MODE_E TM_MODE;
226     uint64_t cores_active;
227
228     uint64_t  * last_trans;
229 };
230
231 struct hash_chain {
232     uint64_t * curr_lt;
233
234     struct list_head lt_node;
235 };
236
237 // called from #PF handler, stages entries, catches reads / writes
238 addr_t v3_handle_trans_mem_fault(struct guest_info *core, 
239                                  addr_t fault_addr, 
240                                  pf_error_t error);
241
242 // restores instruction after core->rip
243 int v3_restore_dirty_instr(struct guest_info *core);
244
245 // restores instruction after core->rip
246 int v3_restore_abort_instr(struct guest_info *core);
247
248 // handles abort cleanup, called from INT/EXCP or XABORT
249 int v3_handle_trans_abort(struct guest_info *core);
250
251 // record a memory access in hashes
252 int tm_record_access (struct v3_trans_mem * tm, 
253                       uint8_t write, 
254                       addr_t gva);
255
256 // garbage collect hash recordings
257 int tm_hash_gc (struct v3_trans_mem * tm);
258
259 // check address for conflicts
260 int tm_check_conflict(struct   v3_vm_info * vm_info,
261                       addr_t   gva,
262                       v3_tm_op_t op_type,
263                       uint64_t core_num, 
264                       uint64_t curr_ctxt);
265
266 // increment transaction number
267 int v3_tm_inc_tnum(struct v3_trans_mem * tm);
268
269
270 /* exception-related functions */
271 int v3_tm_handle_exception(struct guest_info * info, addr_t exit_code);
272
273 void v3_tm_set_excp_intercepts(vmcb_ctrl_t * ctrl_area);
274
275 void v3_tm_check_intr_state(struct guest_info * info, 
276         vmcb_ctrl_t * guest_ctrl, 
277         vmcb_saved_state_t * guest_state);
278
279
280 /* paging-related functions */
281 int v3_tm_handle_pf_64 (struct guest_info * info,
282                         pf_error_t error_code,
283                         addr_t fault_addr,
284                         addr_t * page_to_use);
285
286 void v3_tm_handle_usr_tlb_miss(struct guest_info * info,
287                                pf_error_t error_code,
288                                addr_t page_to_use,
289                                addr_t * shadow_pa);
290
291 void v3_tm_handle_read_fault(struct guest_info * info,
292                              pf_error_t error_code,
293                              pte64_t * shadow_pte);
294
295 #include <palacios/vmm_decoder.h>
296
297 /* decoding-related functions */
298 int v3_tm_decode_rtm_instrs(struct guest_info * info, 
299                             addr_t instr_ptr, 
300                             struct x86_instr * instr);
301
302
303 #endif