lcd-domains-arch.h 6.38 KB
Newer Older
1 2
#ifndef LCD_DOMAINS_ARCH_H
#define LCD_DOMAINS_ARCH_H
3

4
#include <asm/vmx.h>
5 6
#include <linux/spinlock.h>

7
struct lcd_arch_vmcs {
8 9 10 11 12
	u32 revision_id;
	u32 abort;
	char data[0];
};

13
int lcd_arch_autoload_msrs[] = {
14
	/* NONE */
15
};
16
#define LCD_ARCH_NUM_AUTOLOAD_MSRS 0
17

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
enum lcd_arch_reg {
	LCD_ARCH_REGS_RAX = 0,
	LCD_ARCH_REGS_RCX = 1,
	LCD_ARCH_REGS_RDX = 2,
	LCD_ARCH_REGS_RBX = 3,
	LCD_ARCH_REGS_RSP = 4,
	LCD_ARCH_REGS_RBP = 5,
	LCD_ARCH_REGS_RSI = 6,
	LCD_ARCH_REGS_RDI = 7,
	LCD_ARCH_REGS_R8 = 8,
	LCD_ARCH_REGS_R9 = 9,
	LCD_ARCH_REGS_R10 = 10,
	LCD_ARCH_REGS_R11 = 11,
	LCD_ARCH_REGS_R12 = 12,
	LCD_ARCH_REGS_R13 = 13,
	LCD_ARCH_REGS_R14 = 14,
	LCD_ARCH_REGS_R15 = 15,
	LCD_ARCH_REGS_RIP,
	LCD_ARCH_NUM_REGS
37 38
};

Charlie Jacobsen's avatar
Charlie Jacobsen committed
39 40
#define LCD_ARCH_EPT_WALK_LENGTH 4
#define LCD_ARCH_EPTP_WALK_SHIFT 3
41
#define LCD_ARCH_PTRS_PER_EPTE   (1 << 9)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
42

43
struct lcd_arch_ept {
44 45 46 47
	spinlock_t lock;
	unsigned long root_hpa;
	unsigned long vmcs_ptr;
	bool access_dirty_enabled;
48 49
};

Charlie Jacobsen's avatar
Charlie Jacobsen committed
50 51
typedef epte_t lcd_arch_epte_t;

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
struct lcd_arch_tss {
	/*
	 * Intel SDM V3 7.7
	 *
	 * Base TSS before I/O bitmap, etc.
	 */
	struct x86_hw_tss base_tss;
	/*
	 * I/O bitmap must be at least 8 bits to contain
	 * required 8 bits that are set.
	 *
	 * Intel SDM V1 16.5.2
	 */
	u8 io_bitmap[1];
} __attribute__((packed));

Charlie Jacobsen's avatar
Charlie Jacobsen committed
68

69
struct lcd_arch {
70 71 72
	/*
	 * Public Data
	 */
73 74 75 76
	struct {
		u64 gva;
		u64 gpa;
	} run_info;
77 78 79 80

	/*
	 * Private Data
	 */
81 82
	int cpu;
	int launched;
83
	int vpid;
84
	struct lcd_arch_vmcs *vmcs;
85

86
	struct lcd_arch_ept ept;
87 88
	struct desc_struct  *gdt;
	struct lcd_arch_tss *tss;
89 90 91 92 93 94 95 96 97

	u8  fail;
	u64 exit_reason;
	u64 exit_qualification;
	u32 idt_vectoring_info;
	u32 exit_intr_info;
	u32 error_code;
	u32 vec_no;
	u64 host_rsp;
98
	u64 regs[LCD_ARCH_NUM_REGS];
99 100 101 102 103
	u64 cr2;
	int shutdown;
	int ret_code;

	struct msr_autoload {
104 105 106
#if LCD_ARCH_NUM_AUTOLOAD_MSRS > 0
		struct vmx_msr_entry guest[LCD_ARCH_NUM_AUTOLOAD_MSRS];
		struct vmx_msr_entry host[LCD_ARCH_NUM_AUTOLOAD_MSRS];
107 108 109 110
#else
		struct vmx_msr_entry *guest;
		struct vmx_msr_entry *host;
#endif
111 112 113
	} msr_autoload;
};

114 115 116 117
/**
 * Initializes the arch-dependent code for LCD (detects required
 * features, turns on VMX on *all* cpu's).
 */
118
int lcd_arch_init(void);
119 120 121 122 123 124
/**
 * Turns off VMX on *all* cpu's and tears down arch-dependent code.
 * 
 * Important: All LCDs should be destroyed before calling this
 * routine (otherwise, memory will leak).
 */
125
void lcd_arch_exit(void);
126 127 128 129
/**
 * Creates the arch-dependent part of an LCD, and initializes 
 * the settings and most register values.
 */
130
struct lcd_arch *lcd_arch_create(void);
131 132 133 134
/**
 * Tears down arch-dep part of LCD. (If LCD is launched on
 * some cpu, it will become inactive.)
 */
135
void lcd_arch_destroy(struct lcd_arch *vcpu);
136 137 138 139 140
/**
 * Runs the LCD on the calling cpu. (If the LCD is active on
 * a different cpu, it will become inactive there.) Kernel
 * preemption is disabled while the LCD is launched, but
 * external interrupts are not disabled and will be handled.
141 142 143
 *
 * Unless the caller does otherwise, kernel preemption is
 * enabled before returning.
144 145 146 147 148 149 150
 */
int lcd_arch_run(struct lcd_arch *vcpu);

/**
 * Status codes for running LCDs.
 */
enum lcd_arch_status {
151
	LCD_ARCH_STATUS_PAGE_FAULT = 0,
152 153 154
	LCD_ARCH_STATUS_EXT_INTR   = 1,
	LCD_ARCH_STATUS_EPT_FAULT  = 2,
	LCD_ARCH_STATUS_CR3_ACCESS = 3,
155
};
156

Charlie Jacobsen's avatar
Charlie Jacobsen committed
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/**
 * Lookup ept entry for guest physical address gpa.
 *
 * Set create = 1 to allocate ept page table data structures
 * along the path as needed.
 */
int lcd_arch_ept_walk(struct lcd_arch *vcpu, u64 gpa, int create,
		lcd_arch_epte_t **epte_out);
/**
 * Set the guest physical => host physical mapping in the ept entry.
 */
int lcd_arch_ept_set(lcd_arch_epte_t *epte, u64 hpa);
/**
 * Read the host physical address stored in epte.
 */
u64 lcd_arch_ept_hpa(lcd_arch_epte_t *epte);

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
/*
 * GDT Layout
 * ==========
 * 0 = NULL
 * 1 = Code segment
 * 2 = Data segment
 * 3 = Data segment
 * 4 = Task segment
 *
 * See Intel SDM V3 26.3.1.2, 26.3.1.3 for register requirements.
 * See Intel SDM V3 3.4.2, 3.4.3 for segment register layout
 * See Intel SDM V3 2.4.1 - 2.4.4 for gdtr, ldtr, idtr, tr
 */
#define LCD_ARCH_FS_BASE     0x0UL
#define LCD_ARCH_FS_LIMIT    0xFFFFFFFF
#define LCD_ARCH_GS_BASE     0x0UL
#define LCD_ARCH_GS_LIMIT    0xFFFFFFFF
#define LCD_ARCH_GDTR_BASE   0x0000000000002000UL
#define LCD_ARCH_GDTR_LIMIT  ~(PAGE_SIZE - 1)
#define LCD_ARCH_TSS_BASE    0x0000000000003000UL
/* tss base + limit = address of last byte in tss, hence -1 */
#define LCD_ARCH_TSS_LIMIT   (sizeof(struct lcd_arch_tss) - 1)
#define LCD_ARCH_IDTR_BASE   0x0UL
#define LCD_ARCH_IDTR_LIMIT  0x0 /* no idt right now */

#define LCD_ARCH_CS_SELECTOR   (1 << 3)
#define LCD_ARCH_FS_SELECTOR   (2 << 3)
#define LCD_ARCH_GS_SELECTOR   (3 << 3)
#define LCD_ARCH_TR_SELECTOR   (4 << 3) /* TI must be 0 */
#define LCD_ARCH_LDTR_SELECTOR (0 << 3) /* unusable */

/*
 * Guest Physical Memory Layout
 * ============================
 *
 *                         +---------------------------+ 0xFFFF FFFF FFFF FFFF
 *                         |                           |
 *                         :                           :
 *                         :      Free / Unmapped      :
 *                         :                           :
 *                         |                           |
 * LCD_ARCH_STACK_TOP,---> +---------------------------+ 0x0000 0000 0000 4000
 * LCD_ARCH_FREE           |                           |
 *                         |          Stack            |
 *                         :       (grows down)        : (4 KBs)
 *                         :                           :
 *                         |                           |
 *                         |   IPC Message Registers   |
 * LCD_ARCH_IPC_REGS-----> +---------------------------+ 0x0000 0000 0000 3000
 *                         |           TSS             |
 *                         |    only sizeof(tss) is    | (4 KBs)
 *                         |           used            |
 * LCD_ARCH_TSS_BASE-----> +---------------------------+ 0x0000 0000 0000 2000
 *                         |           GDT             | (4 KBs)
 * LCD_ARCH_GDT_BASE-----> +---------------------------+ 0x0000 0000 0000 1000
 *                         |         Reserved          |
 *                         |       (not mapped)        | (4 KBs)
 *                         +---------------------------+ 0x0000 0000 0000 0000
 */
#define LCD_ARCH_IPC_REGS    0x0000000000003000UL
#define LCD_ARCH_STACK_TOP   0x0000000000004000UL
#define LCD_ARCH_FREE        LCD_ARCH_STACK_TOP
Charlie Jacobsen's avatar
Charlie Jacobsen committed
236

237
#endif  /* LCD_DOMAINS_ARCH_H */