/root/src/xen/xen/arch/x86/hvm/vm_event.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * arch/x86/hvm/vm_event.c |
3 | | * |
4 | | * HVM vm_event handling routines |
5 | | * |
6 | | * Copyright (c) 2004, Intel Corporation. |
7 | | * Copyright (c) 2005, International Business Machines Corporation. |
8 | | * Copyright (c) 2008, Citrix Systems, Inc. |
9 | | * |
10 | | * This program is free software; you can redistribute it and/or |
11 | | * modify it under the terms of the GNU General Public |
12 | | * License v2 as published by the Free Software Foundation. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU General Public |
20 | | * License along with this program; If not, see <http://www.gnu.org/licenses/>. |
21 | | */ |
22 | | |
23 | | #include <xen/sched.h> |
24 | | #include <xen/vm_event.h> |
25 | | #include <asm/hvm/support.h> |
26 | | #include <asm/vm_event.h> |
27 | | |
28 | | static void hvm_vm_event_set_registers(const struct vcpu *v) |
29 | 0 | { |
30 | 0 | ASSERT(v == current); |
31 | 0 |
|
32 | 0 | if ( unlikely(v->arch.vm_event->set_gprs) ) |
33 | 0 | { |
34 | 0 | struct cpu_user_regs *regs = guest_cpu_user_regs(); |
35 | 0 |
|
36 | 0 | regs->rax = v->arch.vm_event->gprs.rax; |
37 | 0 | regs->rbx = v->arch.vm_event->gprs.rbx; |
38 | 0 | regs->rcx = v->arch.vm_event->gprs.rcx; |
39 | 0 | regs->rdx = v->arch.vm_event->gprs.rdx; |
40 | 0 | regs->rsp = v->arch.vm_event->gprs.rsp; |
41 | 0 | regs->rbp = v->arch.vm_event->gprs.rbp; |
42 | 0 | regs->rsi = v->arch.vm_event->gprs.rsi; |
43 | 0 | regs->rdi = v->arch.vm_event->gprs.rdi; |
44 | 0 |
|
45 | 0 | regs->r8 = v->arch.vm_event->gprs.r8; |
46 | 0 | regs->r9 = v->arch.vm_event->gprs.r9; |
47 | 0 | regs->r10 = v->arch.vm_event->gprs.r10; |
48 | 0 | regs->r11 = v->arch.vm_event->gprs.r11; |
49 | 0 | regs->r12 = v->arch.vm_event->gprs.r12; |
50 | 0 | regs->r13 = v->arch.vm_event->gprs.r13; |
51 | 0 | regs->r14 = v->arch.vm_event->gprs.r14; |
52 | 0 | regs->r15 = v->arch.vm_event->gprs.r15; |
53 | 0 |
|
54 | 0 | regs->rflags = v->arch.vm_event->gprs.rflags; |
55 | 0 | regs->rip = v->arch.vm_event->gprs.rip; |
56 | 0 |
|
57 | 0 | v->arch.vm_event->set_gprs = false; |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | void hvm_vm_event_do_resume(struct vcpu *v) |
62 | 0 | { |
63 | 0 | struct monitor_write_data *w; |
64 | 0 |
|
65 | 0 | ASSERT(v->arch.vm_event); |
66 | 0 |
|
67 | 0 | hvm_vm_event_set_registers(v); |
68 | 0 |
|
69 | 0 | w = &v->arch.vm_event->write_data; |
70 | 0 |
|
71 | 0 | if ( unlikely(v->arch.vm_event->emulate_flags) ) |
72 | 0 | { |
73 | 0 | enum emul_kind kind = EMUL_KIND_NORMAL; |
74 | 0 |
|
75 | 0 | /* |
76 | 0 | * Please observe the order here to match the flag descriptions |
77 | 0 | * provided in public/vm_event.h |
78 | 0 | */ |
79 | 0 | if ( v->arch.vm_event->emulate_flags & |
80 | 0 | VM_EVENT_FLAG_SET_EMUL_READ_DATA ) |
81 | 0 | kind = EMUL_KIND_SET_CONTEXT_DATA; |
82 | 0 | else if ( v->arch.vm_event->emulate_flags & |
83 | 0 | VM_EVENT_FLAG_EMULATE_NOWRITE ) |
84 | 0 | kind = EMUL_KIND_NOWRITE; |
85 | 0 | else if ( v->arch.vm_event->emulate_flags & |
86 | 0 | VM_EVENT_FLAG_SET_EMUL_INSN_DATA ) |
87 | 0 | kind = EMUL_KIND_SET_CONTEXT_INSN; |
88 | 0 |
|
89 | 0 | hvm_emulate_one_vm_event(kind, TRAP_invalid_op, |
90 | 0 | X86_EVENT_NO_EC); |
91 | 0 |
|
92 | 0 | v->arch.vm_event->emulate_flags = 0; |
93 | 0 | } |
94 | 0 |
|
95 | 0 | if ( unlikely(w->do_write.cr0) ) |
96 | 0 | { |
97 | 0 | if ( hvm_set_cr0(w->cr0, 0) == X86EMUL_EXCEPTION ) |
98 | 0 | hvm_inject_hw_exception(TRAP_gp_fault, 0); |
99 | 0 |
|
100 | 0 | w->do_write.cr0 = 0; |
101 | 0 | } |
102 | 0 |
|
103 | 0 | if ( unlikely(w->do_write.cr4) ) |
104 | 0 | { |
105 | 0 | if ( hvm_set_cr4(w->cr4, 0) == X86EMUL_EXCEPTION ) |
106 | 0 | hvm_inject_hw_exception(TRAP_gp_fault, 0); |
107 | 0 |
|
108 | 0 | w->do_write.cr4 = 0; |
109 | 0 | } |
110 | 0 |
|
111 | 0 | if ( unlikely(w->do_write.cr3) ) |
112 | 0 | { |
113 | 0 | if ( hvm_set_cr3(w->cr3, 0) == X86EMUL_EXCEPTION ) |
114 | 0 | hvm_inject_hw_exception(TRAP_gp_fault, 0); |
115 | 0 |
|
116 | 0 | w->do_write.cr3 = 0; |
117 | 0 | } |
118 | 0 |
|
119 | 0 | if ( unlikely(w->do_write.msr) ) |
120 | 0 | { |
121 | 0 | if ( hvm_msr_write_intercept(w->msr, w->value, 0) == |
122 | 0 | X86EMUL_EXCEPTION ) |
123 | 0 | hvm_inject_hw_exception(TRAP_gp_fault, 0); |
124 | 0 |
|
125 | 0 | w->do_write.msr = 0; |
126 | 0 | } |
127 | 0 | } |
128 | | |
129 | | /* |
130 | | * Local variables: |
131 | | * mode: C |
132 | | * c-file-style: "BSD" |
133 | | * c-basic-offset: 4 |
134 | | * tab-width: 4 |
135 | | * indent-tabs-mode: nil |
136 | | * End: |
137 | | */ |