ia64/xen-unstable

annotate xen/include/asm-x86/hvm/support.h @ 14090:cdc765772f69

hvm: Clean up initialisation of hvm_funcs.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Feb 23 11:32:25 2007 +0000 (2007-02-23)
parents 4d7ee9f4336a
children d2a91b73899a
rev   line source
kaf24@8708 1 /*
kaf24@8708 2 * support.h: HVM support routines used by VT-x and SVM.
kaf24@8708 3 *
kaf24@8708 4 * Leendert van Doorn, leendert@watson.ibm.com
kaf24@8708 5 * Copyright (c) 2005, International Business Machines Corporation.
kaf24@8708 6 *
kaf24@8708 7 * This program is free software; you can redistribute it and/or modify it
kaf24@8708 8 * under the terms and conditions of the GNU General Public License,
kaf24@8708 9 * version 2, as published by the Free Software Foundation.
kaf24@8708 10 *
kaf24@8708 11 * This program is distributed in the hope it will be useful, but WITHOUT
kaf24@8708 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kaf24@8708 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kaf24@8708 14 * more details.
kaf24@8708 15 *
kaf24@8708 16 * You should have received a copy of the GNU General Public License along with
kaf24@8708 17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
kaf24@8708 18 * Place - Suite 330, Boston, MA 02111-1307 USA.
kaf24@8708 19 */
kaf24@8708 20
kaf24@8708 21 #ifndef __ASM_X86_HVM_SUPPORT_H__
kaf24@8708 22 #define __ASM_X86_HVM_SUPPORT_H__
kaf24@8708 23
kaf24@8708 24 #include <xen/sched.h>
kaf24@8708 25 #include <asm/types.h>
kaf24@8708 26 #include <asm/regs.h>
kaf24@8708 27 #include <asm/processor.h>
kaf24@8708 28
kaf24@9113 29 #ifndef NDEBUG
kaf24@8708 30 #define HVM_DEBUG 1
kaf24@9113 31 #else
kfraser@10908 32 #define HVM_DEBUG 1
kaf24@9113 33 #endif
kaf24@8708 34
kaf24@8708 35 static inline shared_iopage_t *get_sp(struct domain *d)
kaf24@8708 36 {
kaf24@8708 37 return (shared_iopage_t *) d->arch.hvm_domain.shared_page_va;
kaf24@8708 38 }
kaf24@8708 39
kaf24@8708 40 static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
kaf24@8708 41 {
kaf24@8708 42 return &get_sp(d)->vcpu_iodata[cpu];
kaf24@8708 43 }
kaf24@8708 44
kaf24@8708 45 /* XXX these are really VMX specific */
kaf24@8708 46 #define TYPE_MOV_TO_DR (0 << 4)
kaf24@8708 47 #define TYPE_MOV_FROM_DR (1 << 4)
kaf24@8708 48 #define TYPE_MOV_TO_CR (0 << 4)
kaf24@8708 49 #define TYPE_MOV_FROM_CR (1 << 4)
kaf24@8708 50 #define TYPE_CLTS (2 << 4)
kaf24@8708 51 #define TYPE_LMSW (3 << 4)
kaf24@8708 52
kaf24@8708 53 enum hval_bitmaps {
kaf24@8708 54 EXCEPTION_BITMAP_TABLE=0,
kaf24@8708 55 };
kaf24@8708 56
kaf24@8708 57 #define EXCEPTION_BITMAP_DE (1 << 0) /* Divide Error */
kaf24@8708 58 #define EXCEPTION_BITMAP_DB (1 << 1) /* Debug */
kaf24@8708 59 #define EXCEPTION_BITMAP_NMI (1 << 2) /* NMI */
kaf24@8708 60 #define EXCEPTION_BITMAP_BP (1 << 3) /* Breakpoint */
kaf24@8708 61 #define EXCEPTION_BITMAP_OF (1 << 4) /* Overflow */
kaf24@8708 62 #define EXCEPTION_BITMAP_BR (1 << 5) /* BOUND Range Exceeded */
kaf24@8708 63 #define EXCEPTION_BITMAP_UD (1 << 6) /* Invalid Opcode */
kaf24@8708 64 #define EXCEPTION_BITMAP_NM (1 << 7) /* Device Not Available */
kaf24@8708 65 #define EXCEPTION_BITMAP_DF (1 << 8) /* Double Fault */
kaf24@8708 66 /* reserved */
kaf24@8708 67 #define EXCEPTION_BITMAP_TS (1 << 10) /* Invalid TSS */
kaf24@8708 68 #define EXCEPTION_BITMAP_NP (1 << 11) /* Segment Not Present */
kaf24@8708 69 #define EXCEPTION_BITMAP_SS (1 << 12) /* Stack-Segment Fault */
kaf24@8708 70 #define EXCEPTION_BITMAP_GP (1 << 13) /* General Protection */
kaf24@8708 71 #define EXCEPTION_BITMAP_PG (1 << 14) /* Page Fault */
kaf24@8708 72 #define EXCEPTION_BITMAP_MF (1 << 16) /* x87 FPU Floating-Point Error (Math Fault) */
kaf24@8708 73 #define EXCEPTION_BITMAP_AC (1 << 17) /* Alignment Check */
kaf24@8708 74 #define EXCEPTION_BITMAP_MC (1 << 18) /* Machine Check */
kaf24@8708 75 #define EXCEPTION_BITMAP_XF (1 << 19) /* SIMD Floating-Point Exception */
kaf24@8708 76
kaf24@8708 77 /* Pending Debug exceptions */
kaf24@8708 78 #define PENDING_DEBUG_EXC_BP (1 << 12) /* break point */
kaf24@8708 79 #define PENDING_DEBUG_EXC_BS (1 << 14) /* Single step */
kaf24@8708 80
kaf24@8708 81 #ifdef XEN_DEBUGGER
kaf24@8708 82 #define MONITOR_DEFAULT_EXCEPTION_BITMAP \
kaf24@8708 83 ( EXCEPTION_BITMAP_PG | \
kaf24@8708 84 EXCEPTION_BITMAP_DB | \
kaf24@8708 85 EXCEPTION_BITMAP_BP | \
kaf24@8708 86 EXCEPTION_BITMAP_GP )
kaf24@8708 87 #else
kaf24@8708 88 #define MONITOR_DEFAULT_EXCEPTION_BITMAP \
kaf24@8708 89 ( EXCEPTION_BITMAP_PG | \
kaf24@9963 90 EXCEPTION_BITMAP_BP )
kaf24@8708 91 #endif
kaf24@8708 92
kaf24@9226 93 #define VMX_DELIVER_NO_ERROR_CODE -1
kaf24@8708 94
kaf24@8708 95 #if HVM_DEBUG
kaf24@8708 96 #define DBG_LEVEL_0 (1 << 0)
kaf24@8708 97 #define DBG_LEVEL_1 (1 << 1)
kaf24@8708 98 #define DBG_LEVEL_2 (1 << 2)
kaf24@8708 99 #define DBG_LEVEL_3 (1 << 3)
kaf24@8708 100 #define DBG_LEVEL_IO (1 << 4)
kaf24@8708 101 #define DBG_LEVEL_VMMU (1 << 5)
kaf24@8708 102 #define DBG_LEVEL_VLAPIC (1 << 6)
kaf24@8708 103 #define DBG_LEVEL_VLAPIC_TIMER (1 << 7)
kaf24@9146 104 #define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 8)
kaf24@8708 105 #define DBG_LEVEL_IOAPIC (1 << 9)
kaf24@8708 106
kaf24@8708 107 extern unsigned int opt_hvm_debug_level;
tdeegan@11172 108 #define HVM_DBG_LOG(level, _f, _a...) \
tdeegan@11172 109 do { \
kfraser@11654 110 if ( unlikely((level) & opt_hvm_debug_level) ) \
tdeegan@11172 111 printk("[HVM:%d.%d] <%s> " _f "\n", \
tdeegan@11172 112 current->domain->domain_id, current->vcpu_id, __func__, \
tdeegan@11172 113 ## _a); \
tdeegan@11172 114 } while (0)
kaf24@8708 115 #else
kaf24@8708 116 #define HVM_DBG_LOG(level, _f, _a...)
kaf24@8708 117 #endif
kaf24@8708 118
kfraser@12282 119 #define TRACE_VMEXIT(index, value) \
kfraser@12282 120 current->arch.hvm_vcpu.hvm_trace_values[index] = (value)
kfraser@12282 121
Tim@13766 122 /*
Tim@13766 123 * Save/restore support
Tim@13766 124 */
Tim@13492 125
Tim@13793 126 /* Marshalling and unmarshalling uses a buffer with size and cursor. */
Tim@13793 127 typedef struct hvm_domain_context {
Tim@13793 128 uint32_t cur;
Tim@13793 129 uint32_t size;
Tim@13793 130 uint8_t *data;
Tim@13793 131 } hvm_domain_context_t;
Tim@13793 132
Tim@13766 133 /* Marshalling an entry: check space and fill in the header */
Tim@13766 134 static inline int _hvm_init_entry(struct hvm_domain_context *h,
Tim@13766 135 uint16_t tc, uint16_t inst, uint32_t len)
Tim@13492 136 {
Tim@13766 137 struct hvm_save_descriptor *d
Tim@13766 138 = (struct hvm_save_descriptor *)&h->data[h->cur];
Tim@13766 139 if ( h->size - h->cur < len + sizeof (*d) )
Tim@13766 140 {
Tim@13766 141 gdprintk(XENLOG_WARNING,
Tim@13766 142 "HVM save: no room for %"PRIu32" + %u bytes "
Tim@13766 143 "for typecode %"PRIu16"\n",
Tim@13766 144 len, (unsigned) sizeof (*d), tc);
Tim@13766 145 return -1;
Tim@13766 146 }
Tim@13766 147 d->typecode = tc;
Tim@13766 148 d->instance = inst;
Tim@13766 149 d->length = len;
Tim@13766 150 h->cur += sizeof (*d);
Tim@13766 151 return 0;
Tim@13492 152 }
Tim@13492 153
Tim@13766 154 /* Marshalling: copy the contents in a type-safe way */
Tim@13766 155 #define _hvm_write_entry(_x, _h, _src) do { \
Tim@13766 156 *(HVM_SAVE_TYPE(_x) *)(&(_h)->data[(_h)->cur]) = *(_src); \
Tim@13766 157 (_h)->cur += HVM_SAVE_LENGTH(_x); \
Tim@13766 158 } while (0)
Tim@13766 159
Tim@13766 160 /* Marshalling: init and copy; evaluates to zero on success */
Tim@13766 161 #define hvm_save_entry(_x, _inst, _h, _src) ({ \
Tim@13766 162 int r; \
Tim@13766 163 r = _hvm_init_entry((_h), HVM_SAVE_CODE(_x), \
Tim@13766 164 (_inst), HVM_SAVE_LENGTH(_x)); \
Tim@13766 165 if ( r == 0 ) \
Tim@13766 166 _hvm_write_entry(_x, (_h), (_src)); \
Tim@13766 167 r; })
Tim@13766 168
Tim@13766 169 /* Unmarshalling: test an entry's size and typecode and record the instance */
Tim@13766 170 static inline int _hvm_check_entry(struct hvm_domain_context *h,
Tim@13766 171 uint16_t type, uint32_t len)
Tim@13492 172 {
Tim@13766 173 struct hvm_save_descriptor *d
Tim@13766 174 = (struct hvm_save_descriptor *)&h->data[h->cur];
Tim@13766 175 if ( len + sizeof (*d) > h->size - h->cur)
Tim@13766 176 {
Tim@13766 177 gdprintk(XENLOG_WARNING,
Tim@13766 178 "HVM restore: not enough data left to read %u bytes "
Tim@13766 179 "for type %u\n", len, type);
Tim@13766 180 return -1;
Tim@13766 181 }
Tim@13766 182 if ( type != d->typecode || len != d->length )
Tim@13766 183 {
Tim@13766 184 gdprintk(XENLOG_WARNING,
Tim@13766 185 "HVM restore mismatch: expected type %u length %u, "
Tim@13766 186 "saw type %u length %u\n", type, len, d->typecode, d->length);
Tim@13492 187 return -1;
Tim@13492 188 }
Tim@13766 189 h->cur += sizeof (*d);
Tim@13766 190 return 0;
Tim@13492 191 }
Tim@13492 192
Tim@13766 193 /* Unmarshalling: copy the contents in a type-safe way */
Tim@13766 194 #define _hvm_read_entry(_x, _h, _dst) do { \
Tim@13766 195 *(_dst) = *(HVM_SAVE_TYPE(_x) *) (&(_h)->data[(_h)->cur]); \
Tim@13766 196 (_h)->cur += HVM_SAVE_LENGTH(_x); \
Tim@13766 197 } while (0)
Tim@13492 198
Tim@13766 199 /* Unmarshalling: check, then copy. Evaluates to zero on success. */
Tim@13766 200 #define hvm_load_entry(_x, _h, _dst) ({ \
Tim@13766 201 int r; \
Tim@13766 202 r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), HVM_SAVE_LENGTH(_x)); \
Tim@13766 203 if ( r == 0 ) \
Tim@13766 204 _hvm_read_entry(_x, (_h), (_dst)); \
Tim@13766 205 r; })
Tim@13492 206
Tim@13766 207 /* Unmarshalling: what is the instance ID of the next entry? */
Tim@13766 208 static inline uint16_t hvm_load_instance(struct hvm_domain_context *h)
Tim@13492 209 {
Tim@13766 210 struct hvm_save_descriptor *d
Tim@13766 211 = (struct hvm_save_descriptor *)&h->data[h->cur];
Tim@13766 212 return d->instance;
Tim@13492 213 }
Tim@13492 214
Tim@13766 215 /* Handler types for different types of save-file entry.
Tim@13766 216 * The save handler may save multiple instances of a type into the buffer;
Tim@13766 217 * the load handler will be called once for each instance found when
Tim@13766 218 * restoring. Both return non-zero on error. */
Tim@13766 219 typedef int (*hvm_save_handler) (struct domain *d,
Tim@13766 220 hvm_domain_context_t *h);
Tim@13766 221 typedef int (*hvm_load_handler) (struct domain *d,
Tim@13766 222 hvm_domain_context_t *h);
Tim@13492 223
Tim@13865 224 /* Init-time function to declare a pair of handlers for a type,
Tim@13865 225 * and the maximum buffer space needed to save this type of state */
Tim@13767 226 void hvm_register_savevm(uint16_t typecode,
Tim@13767 227 const char *name,
Tim@13766 228 hvm_save_handler save_state,
Tim@13865 229 hvm_load_handler load_state,
Tim@13865 230 size_t size, int kind);
Tim@13492 231
Tim@13865 232 /* The space needed for saving can be per-domain or per-vcpu: */
Tim@13865 233 #define HVMSR_PER_DOM 0
Tim@13865 234 #define HVMSR_PER_VCPU 1
Tim@13865 235
Tim@13865 236 /* Syntactic sugar around that function: specify the max number of
Tim@13865 237 * saves, and this calculates the size of buffer needed */
Tim@13865 238 #define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load, _num, _k) \
Tim@13865 239 static int __hvm_register_##_x##_save_and_restore(void) \
Tim@13865 240 { \
Tim@13865 241 hvm_register_savevm(HVM_SAVE_CODE(_x), \
Tim@13865 242 #_x, \
Tim@13865 243 &_save, \
Tim@13865 244 &_load, \
Tim@13865 245 (_num) * (HVM_SAVE_LENGTH(_x) \
Tim@13865 246 + sizeof (struct hvm_save_descriptor)), \
Tim@13865 247 _k); \
Tim@13865 248 return 0; \
Tim@13865 249 } \
Tim@13766 250 __initcall(__hvm_register_##_x##_save_and_restore);
Tim@13541 251
Tim@13766 252
Tim@13766 253 /* Entry points for saving and restoring HVM domain state */
Tim@13865 254 size_t hvm_save_size(struct domain *d);
Tim@13694 255 int hvm_save(struct domain *d, hvm_domain_context_t *h);
Tim@13694 256 int hvm_load(struct domain *d, hvm_domain_context_t *h);
Tim@13492 257
Tim@13766 258 /* End of save/restore */
Tim@13493 259
kfraser@13627 260 extern char hvm_io_bitmap[];
kaf24@8708 261 extern int hvm_enabled;
kaf24@8708 262
kfraser@14090 263 void hvm_enable(struct hvm_function_table *);
kfraser@13627 264
Tim@12064 265 int hvm_copy_to_guest_phys(paddr_t paddr, void *buf, int size);
Tim@12064 266 int hvm_copy_from_guest_phys(void *buf, paddr_t paddr, int size);
kfraser@11677 267 int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size);
kfraser@11677 268 int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size);
kaf24@8708 269
kfraser@11677 270 void hvm_print_line(struct vcpu *v, const char c);
kfraser@11677 271 void hlt_timer_fn(void *data);
kaf24@8708 272
kfraser@10892 273 void hvm_do_hypercall(struct cpu_user_regs *pregs);
kfraser@10892 274
kfraser@11164 275 void hvm_hlt(unsigned long rflags);
kfraser@13242 276 void hvm_triple_fault(void);
kfraser@11164 277
kaf24@8708 278 #endif /* __ASM_X86_HVM_SUPPORT_H__ */