Coverage Report

Created: 2017-10-25 09:10

/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
 */