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.


added basic caching MTRR extension.
[palacios.git] / palacios / src / extensions / ext_mtrr.c
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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.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 #include <palacios/vmm.h>
21 #include <palacios/vmm_extensions.h>
22 #include <palacios/vmm_msr.h>
23
24
25
26 #define MTRR_CAP          0xfe
27
28 #define MTRR_PHYS_BASE_0  0x200
29 #define MTRR_PHYS_MASK_0  0x201
30 #define MTRR_PHYS_BASE_1  0x202
31 #define MTRR_PHYS_MASK_1  0x203
32 #define MTRR_PHYS_BASE_2  0x204
33 #define MTRR_PHYS_MASK_2  0x205
34 #define MTRR_PHYS_BASE_3  0x206
35 #define MTRR_PHYS_MASK_3  0x207
36 #define MTRR_PHYS_BASE_4  0x208
37 #define MTRR_PHYS_MASK_4  0x209
38 #define MTRR_PHYS_BASE_5  0x20a
39 #define MTRR_PHYS_MASK_5  0x20b
40 #define MTRR_PHYS_BASE_6  0x20c
41 #define MTRR_PHYS_MASK_6  0x20d
42 #define MTRR_PHYS_BASE_7  0x20e
43 #define MTRR_PHYS_MASK_7  0x20f
44
45 #define MTRR_FIX_64K_00000 0x250
46 #define MTRR_FIX_16K_80000 0x258
47 #define MTRR_FIX_16K_A0000 0x259
48 #define MTRR_FIX_4K_C0000  0x268
49 #define MTRR_FIX_4K_C8000  0x269
50 #define MTRR_FIX_4K_D0000  0x26a
51 #define MTRR_FIX_4K_D8000  0x26b
52 #define MTRR_FIX_4K_E0000  0x26c
53 #define MTRR_FIX_4K_E8000  0x26d
54 #define MTRR_FIX_4K_F0000  0x26e
55 #define MTRR_FIX_4K_F8000  0x26f
56
57 #define PAT                0x277
58
59 #define MTRR_DEF_TYPE      0x2ff
60
61
62
63
64 struct ia32_pat {
65     union {
66         uint64_t value;
67
68         struct {
69             uint64_t pa_0            : 3;
70             uint64_t rsvd0           : 5;
71             uint64_t pa_1            : 3;
72             uint64_t rsvd1           : 5;
73             uint64_t pa_2            : 3;
74             uint64_t rsvd2           : 5;
75             uint64_t pa_3            : 3;
76             uint64_t rsvd3           : 5;
77             uint64_t pa_4            : 3;
78             uint64_t rsvd4           : 5;
79             uint64_t pa_5            : 3;
80             uint64_t rsvd5           : 5;
81             uint64_t pa_6            : 3;
82             uint64_t rsvd6           : 5;
83             uint64_t pa_7            : 3;
84             uint64_t rsvd7           : 5;
85         } __attribute__((packed));
86     } __attribute__((packed));
87 } __attribute__((packed));
88
89
90 struct mtrr_cap {
91     union {
92         uint64_t value;
93
94         struct {
95             uint64_t var_reg_cnt     : 8;
96             uint64_t fix             : 1;
97             uint64_t rsvd0           : 1;
98             uint64_t wr_combine      : 1;
99             uint64_t rsvd1           : 53;
100         } __attribute__((packed));
101     } __attribute__((packed));
102 } __attribute__((packed));
103
104 struct mtrr_def_type {
105     union {
106         uint64_t value;
107
108         struct {
109             uint64_t def_type        : 8;
110             uint64_t rsvd0           : 2;
111             uint64_t fixed_enable    : 1;
112             uint64_t mtrr_emable     : 1;
113             uint64_t rsvd1           : 52;
114         } __attribute__((packed));
115     } __attribute__((packed));
116 } __attribute__((packed));
117
118
119 struct mtrr_phys_base {
120     union {
121         uint64_t value;
122         
123         struct {
124             uint64_t type            : 8;
125             uint64_t rsvd0           : 4;
126             uint64_t base            : 40;
127             uint64_t rsvd1           : 12;
128         } __attribute__((packed));
129     } __attribute__((packed));
130 } __attribute__((packed));
131
132     
133 struct mtrr_phys_mask {
134     union {
135         uint64_t value;
136         
137         struct {
138             uint64_t rsvd0           : 11;
139             uint64_t valid           : 1;
140             uint64_t mask            : 40;
141             uint64_t rsvd1           : 12;
142         } __attribute__((packed));
143     } __attribute__((packed));
144 } __attribute__((packed));
145
146 struct mtrr_fixed {
147     union {
148         uint64_t value;
149         uint8_t types[8];
150     } __attribute__((packed));
151 } __attribute__((packed));
152
153
154
155 /* AMD Specific Registers */
156 #define SYSCONFIG          0xc0010010
157 #define TOP_MEM            0xc001001a
158 #define TOP_MEM2           0xc001001d
159
160 #define IORR_BASE0         0xc0010016
161 #define IORR_MASK0         0xc0010017
162 #define IORR_BASE1         0xc0010018
163 #define IORR_MASK1         0xc0010019
164
165 struct syscfg_reg {
166     union {
167         uint64_t value;
168
169         struct {
170             uint64_t rsvd0          : 18;
171             uint64_t mfde           : 1; // 1 = enables RdMem and WrMem bits in fixed-range MTRRs
172             uint64_t mfdm           : 1; // 1 = software can modify RdMem and WrMem bits
173             uint64_t mvdm           : 1; // 1 = enables TOP_MEM reg and var range MTRRs
174             uint64_t tom2           : 1; // 1 = enables TOP_MEM2 reg
175             uint64_t tom2_force_wb  : 1; // 1 = enables default mem type for 4GB-TOP_MEM2 range
176             uint64_t rsvd1          : 41;
177         } __attribute__((packed));
178     } __attribute__((packed));
179 } __attribute__((packed));
180
181 struct top_of_mem_reg {
182     union {
183         uint64_t value;
184         
185         struct {
186             uint64_t rsvd0          : 23;
187             uint64_t phys_addr      : 29;
188             uint64_t rsvd1          : 12;
189         } __attribute__((packed));
190     } __attribute__((packed));
191 } __attribute__((packed));
192
193
194 struct iorr_base {
195     union {
196         uint64_t value;
197         
198         struct {
199             uint64_t rsvd0          : 3;
200             uint64_t wrmem          : 1; // 1 = writes go to memory, 0 = writes go to mmap IO
201             uint64_t rdmem          : 1; // 1 = reads go to memory, 0 = reads go to mmap IO
202             uint64_t rsvd1          : 7;
203             uint64_t base           : 40;
204             uint64_t rsvd2          : 12;
205         } __attribute__((packed));
206     } __attribute__((packed));
207 } __attribute__((packed));
208
209 struct iorr_mask {
210     union {
211         uint64_t value;
212
213         struct {
214             uint64_t rsvd0          : 11;
215             uint64_t valid          : 1;
216             uint64_t mask           : 40;
217             uint64_t rsvd1          : 12;
218         } __attribute__((packed));
219     } __attribute__((packed));
220 } __attribute__((packed));
221
222 /* Intel Specific Registers */
223 #define SMRR_PHYS_BASE 0x1f2
224 #define SMRR_PHYS_MASK 0x1f3
225
226 struct smrr_phys_base {
227     union {
228         uint64_t value;
229
230         struct {
231             uint64_t type            : 8;
232             uint64_t rsvd0           : 4;
233             uint64_t base            : 20;
234             uint64_t rsvd1           : 32;
235         } __attribute__((packed));
236     } __attribute__((packed));
237 } __attribute__((packed));
238
239 struct smrr_phys_mask {
240     union {
241         uint64_t value;
242
243         struct {
244             uint64_t rsvd0           : 11;
245             uint64_t valid           : 1;
246             uint64_t mask            : 20;
247             uint64_t rsvd1           : 32;
248         } __attribute__((packed));
249     } __attribute__((packed));
250 } __attribute__((packed));
251
252
253
254 struct mtrr_state {
255     struct ia32_pat pat;
256     struct mtrr_cap cap;
257     struct mtrr_def_type def_type;
258     struct mtrr_phys_base bases[8];
259     struct mtrr_phys_mask masks[8];
260
261     struct mtrr_fixed fixed_64k;
262     struct mtrr_fixed fixed_16k[2];
263     struct mtrr_fixed fixed_4k[8];
264
265     /* AMD specific registers */
266     struct syscfg_reg amd_syscfg;
267     struct top_of_mem_reg amd_tom;
268     struct top_of_mem_reg amd_tom2;
269
270     struct iorr_base iorr_bases[2];
271     struct iorr_mask iorr_masks[2];
272
273     /* Intel Specific registers */
274     struct smrr_phys_base intel_smrr_base;
275     struct smrr_phys_mask intel_smrr_mask;
276
277 };
278
279 static void init_state(struct mtrr_state * state) {
280     state->pat.value = 0x0007040600070406LL;
281     state->cap.value = 0x0000000000000508LL;
282
283     state->amd_syscfg.value = 0x0000000000020601LL;
284     state->amd_tom.value = 0x0000000004000000LL;
285
286     return;
287 }
288
289 static int mtrr_cap_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
290     struct mtrr_state * state = (struct mtrr_state *)priv_data;
291     dst->value = state->cap.value;
292     return 0;
293 }
294
295 static int mtrr_cap_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
296     struct mtrr_state * state = (struct mtrr_state *)priv_data;
297     state->cap.value = src.value;
298     return 0;
299 }
300
301 static int pat_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
302     struct mtrr_state * state = (struct mtrr_state *)priv_data;
303     dst->value = state->pat.value;
304     return 0;
305 }
306
307 static int pat_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
308     struct mtrr_state * state = (struct mtrr_state *)priv_data;
309     state->pat.value = src.value;
310     return 0;
311 }
312
313 static int def_type_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
314     struct mtrr_state * state = (struct mtrr_state *)priv_data;
315     dst->value = state->def_type.value;
316     return 0;
317 }
318
319 static int def_type_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
320     struct mtrr_state * state = (struct mtrr_state *)priv_data;
321     state->def_type.value = src.value;
322     return 0;
323 }
324
325
326 static int mtrr_phys_base_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
327     struct mtrr_state * state = (struct mtrr_state *)priv_data;
328     int base_index = (msr - MTRR_PHYS_BASE_0) / 2;
329     dst->value = state->bases[base_index].value;
330     return 0;
331 }
332
333 static int mtrr_phys_base_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
334     struct mtrr_state * state = (struct mtrr_state *)priv_data;
335     int base_index = (msr - MTRR_PHYS_BASE_0) / 2;
336     state->bases[base_index].value = src.value;
337     return 0;
338 }
339
340 static int mtrr_phys_mask_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
341     struct mtrr_state * state = (struct mtrr_state *)priv_data;
342     int mask_index = (msr - MTRR_PHYS_MASK_0) / 2;
343     dst->value = state->masks[mask_index].value;
344     return 0;
345 }
346
347 static int mtrr_phys_mask_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
348     struct mtrr_state * state = (struct mtrr_state *)priv_data;
349     int mask_index = (msr - MTRR_PHYS_MASK_0) / 2;
350     state->masks[mask_index].value = src.value;
351     return 0;
352 }
353
354 static int mtrr_fix_64k_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
355     struct mtrr_state * state = (struct mtrr_state *)priv_data;
356     dst->value = state->fixed_64k.value;
357     return 0;
358 }
359
360 static int mtrr_fix_64k_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
361     struct mtrr_state * state = (struct mtrr_state *)priv_data;
362     state->fixed_64k.value = src.value;
363     return 0;
364 }
365
366 static int mtrr_fix_16k_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
367     struct mtrr_state * state = (struct mtrr_state *)priv_data;
368     int index = msr - MTRR_FIX_16K_80000;
369     dst->value = state->fixed_16k[index].value;
370     return 0;
371 }
372
373 static int mtrr_fix_16k_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
374     struct mtrr_state * state = (struct mtrr_state *)priv_data;
375     int index = msr - MTRR_FIX_16K_80000;
376     state->fixed_16k[index].value = src.value;
377     return 0;
378 }
379
380 static int mtrr_fix_4k_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
381     struct mtrr_state * state = (struct mtrr_state *)priv_data;
382     int index = msr - MTRR_FIX_4K_C0000;
383     dst->value = state->fixed_4k[index].value;
384     return 0;
385 }
386
387 static int mtrr_fix_4k_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
388     struct mtrr_state * state = (struct mtrr_state *)priv_data;
389     int index = msr - MTRR_FIX_4K_C0000;
390     state->fixed_4k[index].value = src.value;
391     return 0;
392 }
393
394 /* AMD specific registers */
395 static int amd_syscfg_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
396     struct mtrr_state * state = (struct mtrr_state *)priv_data;
397     dst->value = state->amd_syscfg.value;
398     return 0;
399 }
400
401 static int amd_syscfg_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
402     struct mtrr_state * state = (struct mtrr_state *)priv_data;
403     state->amd_syscfg.value = src.value;
404     return 0;
405 }
406
407 static int amd_top_mem_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
408     struct mtrr_state * state = (struct mtrr_state *)priv_data;
409
410     if (msr == TOP_MEM) {
411         dst->value = state->amd_tom.value;
412     } else if (msr == TOP_MEM2) {
413         dst->value = state->amd_tom2.value;
414     }
415
416     return 0;
417 }
418
419 static int amd_top_mem_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
420     struct mtrr_state * state = (struct mtrr_state *)priv_data;
421     
422     if (msr == TOP_MEM) {
423         state->amd_tom.value = src.value;
424     } else if (msr == TOP_MEM2) {
425         state->amd_tom2.value = src.value;
426     }
427
428     return 0;
429 }
430
431
432 static int amd_iorr_base_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
433     struct mtrr_state * state = (struct mtrr_state *)priv_data;
434     int base_index = (msr - IORR_BASE0) / 2;
435     dst->value = state->iorr_bases[base_index].value;
436     return 0;
437 }
438
439 static int amd_iorr_base_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
440     struct mtrr_state * state = (struct mtrr_state *)priv_data;
441     int base_index = (msr - IORR_BASE0) / 2;
442     state->iorr_bases[base_index].value = src.value;
443     return 0;
444 }
445
446 static int amd_iorr_mask_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
447     struct mtrr_state * state = (struct mtrr_state *)priv_data;
448     int mask_index = (msr - IORR_MASK0) / 2;
449     dst->value = state->iorr_masks[mask_index].value;
450     return 0;
451 }
452
453 static int amd_iorr_mask_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
454     struct mtrr_state * state = (struct mtrr_state *)priv_data;
455     int mask_index = (msr - IORR_MASK0) / 2;
456     state->iorr_masks[mask_index].value = src.value;
457     return 0;
458 }
459
460
461 static int intel_smrr_base_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
462     struct mtrr_state * state = (struct mtrr_state *)priv_data;
463     dst->value = state->intel_smrr_base.value;
464     return 0;
465 }
466
467 static int intel_smrr_base_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
468     struct mtrr_state * state = (struct mtrr_state *)priv_data;
469     state->intel_smrr_base.value = src.value;
470     return 0;
471 }
472
473 static int intel_smrr_mask_read(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) {
474     struct mtrr_state * state = (struct mtrr_state *)priv_data;
475     dst->value = state->intel_smrr_mask.value;
476     return 0;
477 }
478
479 static int intel_smrr_mask_write(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) {
480     struct mtrr_state * state = (struct mtrr_state *)priv_data;
481     state->intel_smrr_mask.value = src.value;
482     return 0;
483 }
484
485
486 static int deinit_mtrrs(struct v3_vm_info * vm, void * priv_data) {
487     struct mtrr_state * state = (struct mtrr_state *)priv_data;
488     
489     v3_unhook_msr(vm, MTRR_CAP);
490     v3_unhook_msr(vm, PAT);
491     v3_unhook_msr(vm, MTRR_DEF_TYPE);
492
493     v3_unhook_msr(vm, MTRR_PHYS_BASE_0);
494     v3_unhook_msr(vm, MTRR_PHYS_BASE_1);
495     v3_unhook_msr(vm, MTRR_PHYS_BASE_2);
496     v3_unhook_msr(vm, MTRR_PHYS_BASE_3);
497     v3_unhook_msr(vm, MTRR_PHYS_BASE_4);
498     v3_unhook_msr(vm, MTRR_PHYS_BASE_5);
499     v3_unhook_msr(vm, MTRR_PHYS_BASE_6);
500     v3_unhook_msr(vm, MTRR_PHYS_BASE_7);
501     v3_unhook_msr(vm, MTRR_PHYS_MASK_0);
502     v3_unhook_msr(vm, MTRR_PHYS_MASK_1);
503     v3_unhook_msr(vm, MTRR_PHYS_MASK_2);
504     v3_unhook_msr(vm, MTRR_PHYS_MASK_3);
505     v3_unhook_msr(vm, MTRR_PHYS_MASK_4);
506     v3_unhook_msr(vm, MTRR_PHYS_MASK_5);
507     v3_unhook_msr(vm, MTRR_PHYS_MASK_6);
508     v3_unhook_msr(vm, MTRR_PHYS_MASK_7);
509
510     v3_unhook_msr(vm, MTRR_FIX_64K_00000);
511     v3_unhook_msr(vm, MTRR_FIX_16K_80000);
512     v3_unhook_msr(vm, MTRR_FIX_16K_A0000);
513     v3_unhook_msr(vm, MTRR_FIX_4K_C0000);
514     v3_unhook_msr(vm, MTRR_FIX_4K_C8000);
515     v3_unhook_msr(vm, MTRR_FIX_4K_D0000);
516     v3_unhook_msr(vm, MTRR_FIX_4K_D8000);
517     v3_unhook_msr(vm, MTRR_FIX_4K_E0000);
518     v3_unhook_msr(vm, MTRR_FIX_4K_E8000);
519     v3_unhook_msr(vm, MTRR_FIX_4K_F0000);
520     v3_unhook_msr(vm, MTRR_FIX_4K_F8000);
521
522     /* AMD specific */
523     v3_unhook_msr(vm, SYSCONFIG);
524     v3_unhook_msr(vm, TOP_MEM);
525     v3_unhook_msr(vm, TOP_MEM2);
526
527     v3_unhook_msr(vm, IORR_BASE0);
528     v3_unhook_msr(vm, IORR_BASE1);
529     v3_unhook_msr(vm, IORR_MASK0);
530     v3_unhook_msr(vm, IORR_MASK1);
531             
532     /* Intel Specfic */
533     v3_unhook_msr(vm, SMRR_PHYS_BASE);
534     v3_unhook_msr(vm, SMRR_PHYS_MASK);
535
536
537     V3_Free(state);
538     return 0;
539 }
540
541
542 static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
543     struct mtrr_state * state = NULL;
544     int ret = 0;
545
546     state = V3_Malloc(sizeof(struct mtrr_state));
547     memset(state, 0, sizeof(struct mtrr_state));
548
549     *priv_data = state;
550
551     init_state(state);
552     
553     // hook MSRs
554     ret |= v3_hook_msr(vm, MTRR_CAP, mtrr_cap_read, mtrr_cap_write, state);
555     ret |= v3_hook_msr(vm, PAT, pat_read, pat_write, state);
556     ret |= v3_hook_msr(vm, MTRR_DEF_TYPE, def_type_read, def_type_write, state);
557
558     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_0, mtrr_phys_base_read, mtrr_phys_base_write, state);
559     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_1, mtrr_phys_base_read, mtrr_phys_base_write, state);
560     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_2, mtrr_phys_base_read, mtrr_phys_base_write, state);
561     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_3, mtrr_phys_base_read, mtrr_phys_base_write, state);
562     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_4, mtrr_phys_base_read, mtrr_phys_base_write, state);
563     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_5, mtrr_phys_base_read, mtrr_phys_base_write, state);
564     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_6, mtrr_phys_base_read, mtrr_phys_base_write, state);
565     ret |= v3_hook_msr(vm, MTRR_PHYS_BASE_7, mtrr_phys_base_read, mtrr_phys_base_write, state);
566     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_0, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
567     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_1, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
568     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_2, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
569     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_3, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
570     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_4, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
571     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_5, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
572     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_6, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
573     ret |= v3_hook_msr(vm, MTRR_PHYS_MASK_7, mtrr_phys_mask_read, mtrr_phys_mask_write, state);
574
575     ret |= v3_hook_msr(vm, MTRR_FIX_64K_00000, mtrr_fix_64k_read, mtrr_fix_64k_write, state);
576     ret |= v3_hook_msr(vm, MTRR_FIX_16K_80000, mtrr_fix_16k_read, mtrr_fix_16k_write, state);
577     ret |= v3_hook_msr(vm, MTRR_FIX_16K_A0000, mtrr_fix_16k_read, mtrr_fix_16k_write, state);
578     ret |= v3_hook_msr(vm, MTRR_FIX_4K_C0000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
579     ret |= v3_hook_msr(vm, MTRR_FIX_4K_C8000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
580     ret |= v3_hook_msr(vm, MTRR_FIX_4K_D0000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
581     ret |= v3_hook_msr(vm, MTRR_FIX_4K_D8000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
582     ret |= v3_hook_msr(vm, MTRR_FIX_4K_E0000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
583     ret |= v3_hook_msr(vm, MTRR_FIX_4K_E8000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
584     ret |= v3_hook_msr(vm, MTRR_FIX_4K_F0000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
585     ret |= v3_hook_msr(vm, MTRR_FIX_4K_F8000, mtrr_fix_4k_read, mtrr_fix_4k_write, state);
586     
587     /* AMD Specific */
588     ret |= v3_hook_msr(vm, SYSCONFIG, amd_syscfg_read, amd_syscfg_write, state);
589     ret |= v3_hook_msr(vm, TOP_MEM, amd_top_mem_read, amd_top_mem_write, state);
590     ret |= v3_hook_msr(vm, TOP_MEM2, amd_top_mem_read, amd_top_mem_write, state);
591
592     ret |= v3_hook_msr(vm, IORR_BASE0, amd_iorr_base_read, amd_iorr_base_write, state);
593     ret |= v3_hook_msr(vm, IORR_BASE1, amd_iorr_base_read, amd_iorr_base_write, state);
594     ret |= v3_hook_msr(vm, IORR_MASK0, amd_iorr_mask_read, amd_iorr_mask_write, state);
595     ret |= v3_hook_msr(vm, IORR_MASK1, amd_iorr_mask_read, amd_iorr_mask_write, state);
596     
597
598     /* INTEL specific */
599     ret |= v3_hook_msr(vm, SMRR_PHYS_BASE, intel_smrr_base_read, intel_smrr_base_write, state);
600     ret |= v3_hook_msr(vm, SMRR_PHYS_MASK, intel_smrr_mask_read, intel_smrr_mask_write, state);
601
602     if (ret != 0) {
603         PrintError("Failed to hook all MTRR MSRs. Aborting...\n");
604         deinit_mtrrs(vm, state);
605         return -1;
606     }
607
608
609     return 0;
610 }
611
612
613
614
615 static struct v3_extension_impl mtrr_impl = {
616     .name = "MTRRS",
617     .init = init_mtrrs,
618     .deinit = deinit_mtrrs,
619     .core_init = NULL,
620     .core_deinit = NULL,
621     .on_entry = NULL,
622     .on_exit = NULL
623 };
624
625 register_extension(&mtrr_impl);