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 - 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
35 - parameterized cache model, for generating hardware configuration-based aborts
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
50 * ud2, rsm, rdmsr, wrmsr, hlt, monitor, mwait, xsetbv, vzeroupper, maskmovq, v/maskmovdqu
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
61 * error = handle_start_tx(boxstate,vcorenum);
62 * error = handle_abort(boxstate,vcorenum);
63 * error = handle_commit(boxstate,vcorenum);
65 * should_abort = handle_write(boxstate, vcorenum, physaddr, data, datalen);
66 * should_abort = handle_read(boxstate, vcorenum,physaddr, *data, datalen);
71 * enum {READ,WRITE,BEGIN,ABORT,END} op;
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
84 * // Idea is that we pass writes to cache model, it calls us back to say which
85 * lines on which cores have changed
90 * struct cache_model *model; //
91 * lock_t global_lock; // any handle_* func acquires this first
93 * uint64_t numtransactionsactive;
97 * int handle_write(box,vcore,physaddr,data,datalen) {
101 #ifndef __TRANS_MEM_H__
102 #define __TRANS_MEM_H__
104 #include <palacios/vmm_lock.h>
105 #include <palacios/vmcb.h>
106 #include <palacios/vmm_paging.h>
110 #define TM_KICKBACK_CALL 0x1337
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; })
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
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
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
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)
146 typedef enum tm_abrt_cause {
151 TM_ABORT_UNSPECIFIED,
154 struct v3_tm_access_type {
157 } __attribute__((packed));
159 struct v3_ctxt_tuple {
163 } __attribute__((packed));
165 /* 441-tm: Are we currently in a transaction */
171 /* 441-tm: Current state of the transaction state machine */
179 typedef enum v3_tm_op {
184 struct v3_trans_mem {
185 /* current transaction */
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;
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;
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;
201 /* 441-tm: lets remember things about the next instruction */
202 uint8_t dirty_instr_flag;
205 uchar_t dirty_instr[15];
208 enum TM_MODE_E TM_MODE;
209 enum TM_STATE_E TM_STATE;
212 struct shadow_page_data * staging_page;
214 /* 441-tm: Remember the failsafe addr */
217 /* 441-tm: Save the rax we are about to ruin */
218 v3_reg_t clobbered_rax;
227 uint64_t entry_exits;
230 struct cache_box * box;
232 struct guest_info * ginfo;
239 enum TM_MODE_E TM_MODE;
240 uint64_t cores_active;
242 uint64_t * last_trans;
248 struct list_head lt_node;
251 // called from #PF handler, stages entries, catches reads / writes
252 addr_t v3_handle_trans_mem_fault(struct guest_info *core,
256 // restores instruction after core->rip
257 int v3_restore_dirty_instr(struct guest_info *core);
259 // restores instruction after core->rip
260 int v3_restore_abort_instr(struct guest_info *core);
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);
267 // record a memory access in hashes
268 int tm_record_access (struct v3_trans_mem * tm,
272 // garbage collect hash recordings
273 int tm_hash_gc (struct v3_trans_mem * tm);
275 // check address for conflicts
276 int tm_check_conflict(struct v3_vm_info * vm_info,
282 // increment transaction number
283 int v3_tm_inc_tnum(struct v3_trans_mem * tm);
286 /* exception-related functions */
287 int v3_tm_handle_exception(struct guest_info * info, addr_t exit_code);
289 void v3_tm_set_excp_intercepts(vmcb_ctrl_t * ctrl_area);
291 void v3_tm_check_intr_state(struct guest_info * info,
292 vmcb_ctrl_t * guest_ctrl,
293 vmcb_saved_state_t * guest_state);
296 /* paging-related functions */
297 int v3_tm_handle_pf_64 (struct guest_info * info,
298 pf_error_t error_code,
300 addr_t * page_to_use);
302 void v3_tm_handle_usr_tlb_miss(struct guest_info * info,
303 pf_error_t error_code,
307 void v3_tm_handle_read_fault(struct guest_info * info,
308 pf_error_t error_code,
309 pte64_t * shadow_pte);
311 #include <palacios/vmm_decoder.h>
313 /* decoding-related functions */
314 int v3_tm_decode_rtm_instrs(struct guest_info * info,
316 struct x86_instr * instr);