aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/hvm/hvm.h
blob: 73f3b3127540e4927dbd2cdc2b4bd78ea5d881ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * hvm.h: Hardware virtual machine assist interface definitions.
 *
 * Leendert van Doorn, leendert@watson.ibm.com
 * Copyright (c) 2005, International Business Machines Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 */
#ifndef __ASM_X86_HVM_HVM_H__
#define __ASM_X86_HVM_HVM_H__

/*
 * The hardware virtual machine (HVM) interface abstracts away from the
 * x86/x86_64 CPU virtualization assist specifics. Currently this interface
 * supports Intel's VT-x and AMD's SVM extensions.
 */

struct hvm_function_table {
    /*
     *  Disable HVM functionality
     */
    void (*disable)(void);

    /*
     * Initialize/relinguish HVM guest resources
     */
    int  (*initialize_guest_resources)(struct vcpu *v);
    void (*relinquish_guest_resources)(struct domain *d);

    /*
     * Store and load guest state:
     * 1) load/store guest register state,
     * 2) modify guest state (e.g., set debug flags).
     */
    void (*store_cpu_guest_regs)(
        struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
    void (*load_cpu_guest_regs)(
        struct vcpu *v, struct cpu_user_regs *r);
    /*
     * Examine specifics of the guest state:
     * 1) determine whether the guest is in real or vm8086 mode,
     * 2) determine whether paging is enabled,
     * 3) return the length of the instruction that caused an exit.
     * 4) return the current guest control-register value
     */
    int (*realmode)(struct vcpu *v);
    int (*paging_enabled)(struct vcpu *v);
    int (*instruction_length)(struct vcpu *v);
    unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);

    /*
     * Update specifics of the guest state:
     * 1) TS bit in guest cr0 
     * 2) TSC offset in guest
     */
    void (*stts)(struct vcpu *v);
    void (*set_tsc_offset)(struct vcpu *v, u64 offset);

    void (*init_ap_context)(struct vcpu_guest_context *ctxt,
                            int vcpuid, int trampoline_vector);

    void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
};

extern struct hvm_function_table hvm_funcs;

/*
 * For convenience, we use short hands.
 */
static inline void
hvm_disable(void)
{
    if ( hvm_funcs.disable )
        hvm_funcs.disable();
}

void hvm_create_event_channels(struct vcpu *v);
void hvm_map_io_shared_pages(struct vcpu *v);

static inline int
hvm_initialize_guest_resources(struct vcpu *v)
{
    int ret = 1;
    if ( hvm_funcs.initialize_guest_resources )
        ret = hvm_funcs.initialize_guest_resources(v);
    if ( ret == 1 ) {
        hvm_map_io_shared_pages(v);
        hvm_create_event_channels(v);
    }
    return ret;
}

static inline void
hvm_relinquish_guest_resources(struct domain *d)
{
    if (hvm_funcs.relinquish_guest_resources)
        hvm_funcs.relinquish_guest_resources(d);
}

static inline void
hvm_store_cpu_guest_regs(
    struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs)
{
    hvm_funcs.store_cpu_guest_regs(v, r, crs);
}

static inline void
hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
{
    hvm_funcs.load_cpu_guest_regs(v, r);
}

static inline int
hvm_realmode(struct vcpu *v)
{
    return hvm_funcs.realmode(v);
}

static inline int
hvm_paging_enabled(struct vcpu *v)
{
    return hvm_funcs.paging_enabled(v);
}

static inline int
hvm_instruction_length(struct vcpu *v)
{
    return hvm_funcs.instruction_length(v);
}

void hvm_hypercall_page_initialise(struct domain *d,
                                   void *hypercall_page);

static inline unsigned long
hvm_get_guest_ctrl_reg(struct vcpu *v, unsigned int num)
{
    if ( hvm_funcs.get_guest_ctrl_reg )
        return hvm_funcs.get_guest_ctrl_reg(v, num);
    return 0;                   /* force to fail */
}

extern void hvm_stts(struct vcpu *v);
extern void hvm_set_guest_time(struct vcpu *v, u64 gtime);
extern void hvm_do_resume(struct vcpu *v);

static inline void
hvm_init_ap_context(struct vcpu_guest_context *ctxt,
                    int vcpuid, int trampoline_vector)
{
    return hvm_funcs.init_ap_context(ctxt, vcpuid, trampoline_vector);
}

extern int hvm_bringup_ap(int vcpuid, int trampoline_vector);

#endif /* __ASM_X86_HVM_HVM_H__ */