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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
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>
19 * This is free software. You are permitted to use,
20 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
23 RTM Implementation Wishlist (roughly in order of priority)
24 Kyle Hale, Maciek Swiech 2014
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
29 - architectural registers need to be saved / restored
30 - exceptions that misuse of TSX instructions can raise
31 - abort on interrupts, asynchronous events
32 - abort on CPUID, PAUSE
33 - abort on non-writeback memory ops, including ifetches to uncacheable mem
34 - RTM-debugger support
36 - parameterized cache model, for generating hardware configuration-based aborts
38 - to be able to model specific implementations, add options (runtime or compiletime) to abort on:
39 * x86/mmx state changes, (also fxstor, fxsave),
40 * cli, sti, popfd, popfq, clts
41 * mov to segment regs, pop segment regs, lds, les, lfs, lgs, lss, swapgs, wrfsbase, wrgsbase, lgdt, sgdt, lidt, sidt, lldt, sldt, ltr,
42 str, far call, far jmp, far ret, far iret, mov to DRx, mov to cr0-4, cr8 lmsw
43 * sysenter, syscall, sysexit, sysret
44 * clflush, invd, wbinvd, invlpg, invpcid
45 * memory instructions with temporal hints (e.g. movntdqa)
46 * xsave, xsaveopt, xrstor
47 * interrupts: INTn, INTO
48 * IO: in, ins, rep ins, out, outs, rep outs, and variants
51 * ud2, rsm, rdmsr, wrmsr, hlt, monitor, mwait, xsetbv, vzeroupper, maskmovq, v/maskmovdqu
55 * We claim that we can have a single, shared "cache"-like box
56 * that handles all writes and reads when TM is on on any core. The
57 * idea is that if TM is on on any core, we redirect reads/writes
58 * that we get to the box, and it records them internally for
59 * future playback, and tells us whether an abort condition has
62 * error = handle_start_tx(boxstate,vcorenum);
63 * error = handle_abort(boxstate,vcorenum);
64 * error = handle_commit(boxstate,vcorenum);
66 * should_abort = handle_write(boxstate, vcorenum, physaddr, data, datalen);
67 * should_abort = handle_read(boxstate, vcorenum,physaddr, *data, datalen);
72 * enum {READ,WRITE,BEGIN,ABORT,END} op;
79 * struct cache_model {
80 * void *init(xml spec); // make a cache, return ptr to state
81 * int write(void *priv, physaddr, datalen, int (*change_cb(int core,
82 * physaddrstart, len));
83 * // similiar for read
85 * // Idea is that we pass writes to cache model, it calls us back to say which
86 * lines on which cores have changed
91 * struct cache_model *model; //
92 * lock_t global_lock; // any handle_* func acquires this first
94 * uint64_t numtransactionsactive;
98 * int handle_write(box,vcore,physaddr,data,datalen) {
102 #ifndef __TRANS_MEM_H__
103 #define __TRANS_MEM_H__
105 #include <palacios/vmm_lock.h>
106 #include <palacios/vmcb.h>
107 #include <palacios/vmm_paging.h>
111 #define TM_KICKBACK_CALL 0x1337
113 #define HTABLE_SEARCH(h, k) ({ addr_t ret; v3_lock(h##_lock); ret = v3_htable_search((h), (k)); v3_unlock(h##_lock); ret; })
114 #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 #define INSTR_INJECT_LEN 10
117 #define INSTR_BUF_SZ 15
118 #define ERR_STORE_MUST_ABORT -2
119 #define ERR_STORE_FAIL -1
120 #define ERR_DECODE_FAIL -1
121 #define ERR_TRANS_FAULT_FAIL 0
122 #define TRANS_FAULT_OK 1
123 #define TRANS_HCALL_FAIL -1
124 #define TRANS_HCALL_OK 0
126 /* conflict checking codes */
127 #define ERR_CHECK_FAIL -1
128 #define CHECK_MUST_ABORT -2
129 #define CHECK_IS_CONFLICT 1
130 #define CHECK_NO_CONFLICT 0
132 /* RTM instruction handling */
133 #define XBEGIN_INSTR_LEN 0x6
134 #define XEND_INSTR_LEN 0x3
135 #define XABORT_INSTR_LEN 0x3
136 #define XTEST_INSTR_LEN 0x3
138 /* abort status definitions (these are bit indeces) */
139 #define ABORT_XABORT 0x0 // xabort instr
140 #define ABORT_RETRY 0x1 // may succeed on retry (must be clear if bit 0 set)
141 #define ABORT_CONFLICT 0x2 // another process accessed memory in the transaction
142 #define ABORT_OFLOW 0x3 // internal buffer overflowed
143 #define ABORT_BKPT 0x4 // debug breakpoint was hit
144 #define ABORT_NESTED 0x5 // abort occured during nested transaction (not currently used)
147 typedef enum tm_abrt_cause {
152 TM_ABORT_UNSPECIFIED,
155 struct v3_tm_access_type {
158 } __attribute__((packed));
160 struct v3_ctxt_tuple {
164 } __attribute__((packed));
166 /* 441-tm: Are we currently in a transaction */
172 /* 441-tm: Current state of the transaction state machine */
180 typedef enum v3_tm_op {
185 struct v3_trans_mem {
186 /* current transaction */
189 /* 441-tm: linked list to store core's reads and writes */
190 struct list_head trans_r_list;
191 struct list_head trans_w_list;
193 /* 441-tm: hash tables of addresses */
194 struct hashtable * addr_ctxt; // records the core transaction context at time of address use
195 v3_lock_t addr_ctxt_lock;
196 uint64_t addr_ctxt_entries;
198 struct hashtable * access_type; // hashes addr:corenum:t_num for each address use
199 v3_lock_t access_type_lock;
200 uint64_t access_type_entries;
202 /* 441-tm: lets remember things about the next instruction */
203 uint8_t dirty_instr_flag;
206 uchar_t dirty_instr[15];
209 enum TM_MODE_E TM_MODE;
210 enum TM_STATE_E TM_STATE;
213 struct shadow_page_data * staging_page;
215 /* 441-tm: Remember the failsafe addr */
218 /* 441-tm: Save the rax we are about to ruin */
219 v3_reg_t clobbered_rax;
228 uint64_t entry_exits;
231 struct cache_box * box;
233 struct guest_info * ginfo;
240 enum TM_MODE_E TM_MODE;
241 uint64_t cores_active;
243 uint64_t * last_trans;
249 struct list_head lt_node;
252 // called from #PF handler, stages entries, catches reads / writes
253 addr_t v3_handle_trans_mem_fault(struct guest_info *core,
257 // restores instruction after core->rip
258 int v3_restore_dirty_instr(struct guest_info *core);
260 // restores instruction after core->rip
261 int v3_restore_abort_instr(struct guest_info *core);
263 // handles abort cleanup, called from INT/EXCP or XABORT
264 int v3_handle_trans_abort(struct guest_info *core,
265 tm_abrt_cause_t cause,
266 uint8_t xabort_reason);
268 // record a memory access in hashes
269 int tm_record_access (struct v3_trans_mem * tm,
273 // garbage collect hash recordings
274 int tm_hash_gc (struct v3_trans_mem * tm);
276 // check address for conflicts
277 int tm_check_conflict(struct v3_vm_info * vm_info,
283 // increment transaction number
284 int v3_tm_inc_tnum(struct v3_trans_mem * tm);
287 /* exception-related functions */
288 int v3_tm_handle_exception(struct guest_info * info, addr_t exit_code);
290 void v3_tm_set_excp_intercepts(vmcb_ctrl_t * ctrl_area);
292 void v3_tm_check_intr_state(struct guest_info * info,
293 vmcb_ctrl_t * guest_ctrl,
294 vmcb_saved_state_t * guest_state);
297 /* paging-related functions */
298 int v3_tm_handle_pf_64 (struct guest_info * info,
299 pf_error_t error_code,
301 addr_t * page_to_use);
303 void v3_tm_handle_usr_tlb_miss(struct guest_info * info,
304 pf_error_t error_code,
308 void v3_tm_handle_read_fault(struct guest_info * info,
309 pf_error_t error_code,
310 pte64_t * shadow_pte);
312 #include <palacios/vmm_decoder.h>
314 /* decoding-related functions */
315 int v3_tm_decode_rtm_instrs(struct guest_info * info,
317 struct x86_instr * instr);