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.


Expose HVM state to host + Linux host /proc additions for it
[palacios.git] / palacios / include / palacios / vmm_fp.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) 2013, Peter Dinda <pdinda@northwestern.edu> 
11  * Copyright (c) 2013, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Peter Dinda <pdinda@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #ifndef __VMM_FP_H
21 #define __VMM_FP_H
22
23 #include <palacios/vmm_types.h>
24 #include <palacios/vmm.h>
25 #ifdef V3_CONFIG_LAZY_FPU_SWITCH
26 #include <interfaces/vmm_lazy_fpu.h>
27 #endif
28
29 // the FPRs are arranged into the 
30 // precise layout of the FXSAVE/FXRESTORE instructions 
31 // bytes 32+, which is common for all three variants
32 // 8*6 reserved + 8*10 (fpu/mmx) + 16*16 (xmm) 
33 // + 3*16 (res) + 3*16 (ava) = 480 bytes
34 // another 32 bytes are used for the store header
35 // which varies depending on machine mode
36 struct v3_fp_regs {
37   v3_fp_mmx_reg_t   stmm0;  // stmm0..7 are the x87 stack or mmx regs
38   uint8_t           res0[6]; 
39   v3_fp_mmx_reg_t   stmm1;  
40   uint8_t           res1[6]; 
41   v3_fp_mmx_reg_t   stmm2;  
42   uint8_t           res2[6]; 
43   v3_fp_mmx_reg_t   stmm3;  
44   uint8_t           res3[6]; 
45   v3_fp_mmx_reg_t   stmm4;  
46   uint8_t           res4[6]; 
47   v3_fp_mmx_reg_t   stmm5;
48   uint8_t           res5[6]; 
49   v3_fp_mmx_reg_t   stmm6;  
50   uint8_t           res6[6]; 
51   v3_fp_mmx_reg_t   stmm7;  
52   uint8_t           res7[6]; 
53   v3_xmm_reg_t      xmm0;   // xmm0..7 are the "classic" SSE regs
54   v3_xmm_reg_t      xmm1;
55   v3_xmm_reg_t      xmm2;
56   v3_xmm_reg_t      xmm3;
57   v3_xmm_reg_t      xmm4;
58   v3_xmm_reg_t      xmm5;
59   v3_xmm_reg_t      xmm6;
60   v3_xmm_reg_t      xmm7;
61   v3_xmm_reg_t      xmm8;    //xmm8..15 are the "new" SSE reg
62   v3_xmm_reg_t      xmm9;
63   v3_xmm_reg_t      xmm10;
64   v3_xmm_reg_t      xmm11;
65   v3_xmm_reg_t      xmm12;
66   v3_xmm_reg_t      xmm13;
67   v3_xmm_reg_t      xmm14;
68   v3_xmm_reg_t      xmm15;
69   v3_xmm_reg_t      res16;  // reserved
70   v3_xmm_reg_t      res17;
71   v3_xmm_reg_t      res18;
72   v3_xmm_reg_t      ava19;
73   v3_xmm_reg_t      ava20;
74   v3_xmm_reg_t      ava21;
75 } __attribute__((packed)) __attribute__((aligned(16)));
76
77 // FXSAVE, 32 bit mode header (32 bytes)
78 // V3_FP_MODE_32
79 struct v3_fp_32_state {
80   uint16_t          fcw;
81   uint16_t          fsw;
82   uint8_t           ftw;
83   uint8_t           res0;
84   uint16_t          fop;
85   uint32_t          fip; //fpu instruction pointer
86   uint16_t          fcs; //fpu code segment selector
87   uint16_t          res1;
88   uint32_t          fdp; //fpu data pointer
89   uint16_t          fds; //fpu data segment selector
90   uint16_t          res2;
91   uint32_t          mxcsr;
92   uint32_t          mxcsr_mask;
93 } __attribute__((packed)) __attribute__((aligned(16)));
94
95 // FXSAVE, 64 bit mode header, REX.W=1 (32 bytes)
96 // V3_FP_MODE_64
97 struct v3_fp_64_state {
98   uint16_t          fcw;
99   uint16_t          fsw;
100   uint8_t           ftw;
101   uint8_t           res0;
102   uint16_t          fop;
103   uint64_t          fip; //fpu instruction pointer
104   uint64_t          fdp; //fpu data pointer
105   uint32_t          mxcsr;
106   uint32_t          mxcsr_mask;
107 } __attribute__((packed)) __attribute__((aligned(16)));
108
109
110 // FXSAVE, 64 bit mode header, REX.W=0 (32 bytes)
111 // V3_FP_MODE_64_COMPAT
112 struct v3_fp_64compat_state {
113   uint16_t          fcw;
114   uint16_t          fsw;
115   uint8_t           ftw;
116   uint8_t           res0;
117   uint16_t          fop;
118   uint32_t          fip; //fpu instruction pointer
119   uint16_t          fcs; //fpu code segment selector
120   uint16_t          res1;
121   uint32_t          fdp; //fpu data pointer
122   uint16_t          fds; //fpu data segment selector
123   uint16_t          res2;
124   uint32_t          mxcsr;
125   uint32_t          mxcsr_mask;
126 } __attribute__((packed)) __attribute__((aligned(16)));
127
128
129 //
130 // This is an FXSAVE block
131 //    
132 struct v3_fp_state_core {
133   union {
134     struct v3_fp_32_state fp32;
135     struct v3_fp_64_state fp64;
136     struct v3_fp_64compat_state fp64compat;
137   } header;
138   struct v3_fp_regs fprs;
139 } __attribute__((packed)) __attribute__((aligned(16)));
140   
141 struct v3_fp_state {
142   // Do we need to restore on next entry?
143   int need_restore;
144   // The meaning 
145   enum {V3_FP_MODE_32=0, V3_FP_MODE_64, V3_FP_MODE_64_COMPAT} state_type;
146   struct v3_fp_state_core  state __attribute__((aligned(16)));
147 } ;
148
149
150 struct guest_info;
151
152 // Can we save FP state on this core?
153 int v3_can_handle_fp_state(); 
154
155 // Save state from this core to the structure
156 int v3_get_fp_state(struct guest_info *core);
157
158 // Restore FP state from this structure to this core
159 int v3_put_fp_state(struct guest_info *core);
160
161 int v3_init_fp(void);
162 int v3_deinit_fp(void);
163
164 #ifndef V3_CONFIG_FP_SWITCH
165
166 /* Ideally these would use the TS trick to do lazy calls to used_fpu() */
167 #define V3_FP_EXIT_SAVE(core)
168
169 #define V3_FP_ENTRY_RESTORE(core)                                           \
170   do {                                                                      \
171     if ((core)->fp_state.need_restore) {                                    \
172       v3_put_fp_state(core);                                \
173       (core)->fp_state.need_restore=0;                                      \
174     }                                                       \
175   } while (0)
176
177 #else
178
179 #ifdef V3_CONFIG_LAZY_FPU_SWITCH
180
181
182 /* Ideally these would use the TS trick to do lazy calls to used_fpu() */
183 #define V3_FP_EXIT_SAVE(core)                                               \
184   do {                                                                      \
185     extern struct v3_lazy_fpu_hooks * lazy_fpu_hooks;                       \
186     if ((lazy_fpu_hooks) && (lazy_fpu_hooks)->used_fpu)                   { \
187       (lazy_fpu_hooks)->used_fpu();                                         \
188     } else {                                                                \
189       v3_get_fp_state(core);                                                \
190     }                                                                       \
191   } while (0)
192
193 #define V3_FP_ENTRY_RESTORE(core)                                           \
194   do {                                                                      \
195     extern struct v3_lazy_fpu_hooks * lazy_fpu_hooks;                       \
196     if ((core)->fp_state.need_restore) {                                    \
197       v3_put_fp_state(core);                                                \
198       (core)->fp_state.need_restore=0;                                      \
199     } else {                                                                \
200         if ((lazy_fpu_hooks) && (lazy_fpu_hooks)->will_use_fpu)           { \
201         (lazy_fpu_hooks)->need_fpu();                                       \
202        } else {                                                             \
203          v3_put_fp_state(core);                                             \
204        }                                                                    \
205     }                                                                       \
206   } while (0)
207
208 #else
209
210 // conservative FPU switching
211
212 #define V3_FP_EXIT_SAVE(core) v3_get_fp_state(core)
213 #define V3_FP_ENTRY_RESTORE(core) v3_put_fp_state(core)
214
215 #endif
216
217 #endif
218
219 #ifdef V3_CONFIG_CHECKPOINT
220
221 struct v3_chkpt_ctx;
222
223 // save state from structure to checkpoint/migration context
224 int v3_save_fp_state(struct v3_chkpt_ctx *ctx, struct guest_info *core);
225
226 // load state from checkpoint/migration context to structure
227 int v3_load_fp_state(struct v3_chkpt_ctx *ctx, struct guest_info *core);
228
229
230 #endif
231
232 #endif