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.


f8d980e368fff726fd177e497409dbff5403232d
[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  *
24  * We claim that we can have a single, shared "cache"-like box
25  * that handles all writes and reads when TM is on on any core.  The
26  * idea is that if TM is on on any core, we redirect reads/writes
27  * that we get to the box, and it records them internally for 
28  * future playback, and tells us whether an abort condition has
29  * occured or not:
30  *
31  * error = handle_start_tx(boxstate,vcorenum);
32  * error = handle_abort(boxstate,vcorenum);
33  * error = handle_commit(boxstate,vcorenum);
34  *
35  * should_abort = handle_write(boxstate, vcorenum, physaddr, data, datalen);
36  * should_abort = handle_read(boxstate, vcorenum,physaddr, *data, datalen);
37  *
38  * One implementation:
39  *
40  * struct rec {
41  *    enum {READ,WRITE,BEGIN,ABORT,END} op;
42  *    addr_t vcorenum,
43  *           physaddr,
44  *           datalen ;
45  *    struct rec *next;
46  * }
47  *
48  * struct cache_model {
49  *    void *init(xml spec);  // make a cache, return ptr to state
50  *    int write(void *priv, physaddr, datalen, int (*change_cb(int core,
51  *                             physaddrstart, len));
52  *    // similiar for read
53  *
54  * // Idea is that we pass writes to cache model, it calls us back to say which
55  * lines on which cores have changed
56  * }
57  *
58  *
59  * struct boxstate {
60  *    struct cache_model *model; //
61  *    lock_t     global_lock; // any handle_* func acquires this first
62  *    uint64_t   loglen;
63  *    uint64_t   numtransactionsactive;
64  *    struct rec *first;
65  * }
66  *
67  * int handle_write(box,vcore,physaddr,data,datalen) {
68  *
69  */
70
71 #ifndef __TRANS_MEM_H__
72 #define __TRANS_MEM_H__
73
74 #include <palacios/vmm_lock.h>
75 #include <palacios/vmcb.h>
76 #include <palacios/vmm_paging.h>
77
78 #define MAX_CORES 32
79
80 #define TM_KICKBACK_CALL 0x1337
81
82 #define HTABLE_SEARCH(h, k) ({ addr_t ret; v3_lock(h##_lock); ret = v3_htable_search((h), (k)); v3_unlock(h##_lock); ret; })
83 #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; })
84
85 #define INSTR_INJECT_LEN 10
86 #define INSTR_BUF_SZ  15
87 #define ERR_STORE_MUST_ABORT -2
88 #define ERR_STORE_FAIL -1
89 #define ERR_DECODE_FAIL -1
90 #define ERR_TRANS_FAULT_FAIL 0
91 #define TRANS_FAULT_OK 1
92 #define TRANS_HCALL_FAIL -1 
93 #define TRANS_HCALL_OK 0
94
95 /* conflict checking codes */
96 #define ERR_CHECK_FAIL -1
97 #define CHECK_MUST_ABORT -2
98 #define CHECK_IS_CONFLICT 1
99 #define CHECK_NO_CONFLICT 0
100
101 /* RTM instruction handling */
102 #define XBEGIN_INSTR_LEN 0x6
103 #define XEND_INSTR_LEN   0x3
104 #define XABORT_INSTR_LEN 0x3
105 #define XTEST_INSTR_LEN  0x3
106
107
108 struct v3_tm_access_type {
109     uint8_t r : 1;
110     uint8_t w : 1;
111 } __attribute__((packed));
112
113 struct v3_ctxt_tuple {
114     void * gva;
115     void * core_id;
116     void * core_lt;
117 } __attribute__((packed));
118
119 /* 441-tm: Are we currently in a transaction */
120 enum TM_MODE_E { 
121     TM_OFF = 0, 
122     TM_ON = 1,
123 };
124
125 /* 441-tm: Current state of the transaction state machine */
126 enum TM_STATE_E {
127     TM_NULL = 0,
128     TM_IFETCH = 1,
129     TM_EXEC = 2
130 //    TM_ABORT = 3
131 };
132
133 typedef enum v3_tm_op {
134     OP_TYPE_READ,
135     OP_TYPE_WRITE
136 } v3_tm_op_t;
137
138 struct v3_trans_mem {
139     /* current transaction */
140     uint64_t t_num;
141
142     /* 441-tm: linked list to store core's reads and writes */
143     struct list_head trans_r_list;
144     struct list_head trans_w_list;
145
146     /* 441-tm: hash tables of addresses */
147     struct hashtable * addr_ctxt;       // records the core transaction context at time of address use
148     v3_lock_t addr_ctxt_lock;
149     uint64_t addr_ctxt_entries;
150
151     struct hashtable * access_type;     // hashes addr:corenum:t_num for each address use
152     v3_lock_t access_type_lock;
153     uint64_t access_type_entries;
154
155     /* 441-tm: lets remember things about the next instruction */
156     uint8_t dirty_instr_flag;
157     addr_t  dirty_hva;
158     addr_t  dirty_gva;
159     uchar_t dirty_instr[15];
160     int     cur_instr_len;
161
162     enum TM_MODE_E TM_MODE;
163     enum TM_STATE_E TM_STATE;
164     uint64_t TM_ABORT;
165
166     struct shadow_page_data * staging_page;
167
168     /* 441-tm: Remember the failsafe addr */
169     addr_t  fail_call;
170
171     /* 441-tm: Save the rax we are about to ruin */
172     v3_reg_t clobbered_rax;
173
174     // branching instrs
175     int to_branch;
176     addr_t offset;
177
178     // timing info
179     uint64_t entry_time;
180     uint64_t exit_time;
181     uint64_t entry_exits;
182
183     // cache box
184     struct cache_box * box;
185
186     struct guest_info * ginfo;
187
188 };
189
190
191 struct v3_tm_state {
192     v3_lock_t lock;
193     enum TM_MODE_E TM_MODE;
194     uint64_t cores_active;
195
196     uint64_t  * last_trans;
197 };
198
199 struct hash_chain {
200     uint64_t * curr_lt;
201
202     struct list_head lt_node;
203 };
204
205 // called from #PF handler, stages entries, catches reads / writes
206 addr_t v3_handle_trans_mem_fault(struct guest_info *core, 
207                                  addr_t fault_addr, 
208                                  pf_error_t error);
209
210 // restores instruction after core->rip
211 int v3_restore_dirty_instr(struct guest_info *core);
212
213 // restores instruction after core->rip
214 int v3_restore_abort_instr(struct guest_info *core);
215
216 // handles abort cleanup, called from INT/EXCP or XABORT
217 int v3_handle_trans_abort(struct guest_info *core);
218
219 // record a memory access in hashes
220 int tm_record_access (struct v3_trans_mem * tm, 
221                       uint8_t write, 
222                       addr_t gva);
223
224 // garbage collect hash recordings
225 int tm_hash_gc (struct v3_trans_mem * tm);
226
227 // check address for conflicts
228 int tm_check_conflict(struct   v3_vm_info * vm_info,
229                       addr_t   gva,
230                       v3_tm_op_t op_type,
231                       uint64_t core_num, 
232                       uint64_t curr_ctxt);
233
234 // increment transaction number
235 int v3_tm_inc_tnum(struct v3_trans_mem * tm);
236
237
238 /* exception-related functions */
239 int v3_tm_handle_exception(struct guest_info * info, addr_t exit_code);
240
241 void v3_tm_set_excp_intercepts(vmcb_ctrl_t * ctrl_area);
242
243 void v3_tm_check_intr_state(struct guest_info * info, 
244         vmcb_ctrl_t * guest_ctrl, 
245         vmcb_saved_state_t * guest_state);
246
247
248 /* paging-related functions */
249 int v3_tm_handle_pf_64 (struct guest_info * info,
250                         pf_error_t error_code,
251                         addr_t fault_addr,
252                         addr_t * page_to_use);
253
254 void v3_tm_handle_usr_tlb_miss(struct guest_info * info,
255                                pf_error_t error_code,
256                                addr_t page_to_use,
257                                addr_t * shadow_pa);
258
259 void v3_tm_handle_read_fault(struct guest_info * info,
260                              pf_error_t error_code,
261                              pte64_t * shadow_pte);
262
263 #include <palacios/vmm_decoder.h>
264
265 /* decoding-related functions */
266 int v3_tm_decode_rtm_instrs(struct guest_info * info, 
267                             addr_t instr_ptr, 
268                             struct x86_instr * instr);
269
270
271 #endif