lcd-domains-arch.h 3.47 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
};

39 40 41
#define LCD_ARCH_CS_SELECTOR 1
#define LCD_ARCH_FS_SELECTOR 2
#define LCD_ARCH_GS_SELECTOR 3
42

Charlie Jacobsen's avatar
Charlie Jacobsen committed
43 44
#define LCD_ARCH_EPT_WALK_LENGTH 4
#define LCD_ARCH_EPTP_WALK_SHIFT 3
45
#define LCD_ARCH_PTRS_PER_EPTE   (1 << 9)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
46

47
struct lcd_arch_ept {
48 49 50 51
	spinlock_t lock;
	unsigned long root_hpa;
	unsigned long vmcs_ptr;
	bool access_dirty_enabled;
52 53
};

Charlie Jacobsen's avatar
Charlie Jacobsen committed
54 55 56
typedef epte_t lcd_arch_epte_t;


57
struct lcd_arch {
58 59 60
	/*
	 * Public Data
	 */
61 62 63 64
	struct {
		u64 gva;
		u64 gpa;
	} run_info;
65 66 67 68

	/*
	 * Private Data
	 */
69 70
	int cpu;
	int launched;
71
	int vpid;
72 73
	struct lcd_arch_vmcs *vmcs;
	struct lcd_arch_ept ept;
74 75 76 77 78 79 80 81 82 83
	struct desc_struct *gdt;

	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;
84
	u64 regs[LCD_ARCH_NUM_REGS];
85 86 87 88 89
	u64 cr2;
	int shutdown;
	int ret_code;

	struct msr_autoload {
90 91 92
#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];
93 94 95 96
#else
		struct vmx_msr_entry *guest;
		struct vmx_msr_entry *host;
#endif
97 98 99
	} msr_autoload;
};

100 101 102 103
/**
 * Initializes the arch-dependent code for LCD (detects required
 * features, turns on VMX on *all* cpu's).
 */
104
int lcd_arch_init(void);
105 106 107 108 109 110
/**
 * 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).
 */
111
void lcd_arch_exit(void);
112 113 114 115
/**
 * Creates the arch-dependent part of an LCD, and initializes 
 * the settings and most register values.
 */
116
struct lcd_arch *lcd_arch_create(void);
117 118 119 120
/**
 * Tears down arch-dep part of LCD. (If LCD is launched on
 * some cpu, it will become inactive.)
 */
121
void lcd_arch_destroy(struct lcd_arch *vcpu);
122 123 124 125 126
/**
 * 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.
127 128 129
 *
 * Unless the caller does otherwise, kernel preemption is
 * enabled before returning.
130 131 132 133 134 135 136
 */
int lcd_arch_run(struct lcd_arch *vcpu);

/**
 * Status codes for running LCDs.
 */
enum lcd_arch_status {
137
	LCD_ARCH_STATUS_PAGE_FAULT = 0,
138 139 140
	LCD_ARCH_STATUS_EXT_INTR   = 1,
	LCD_ARCH_STATUS_EPT_FAULT  = 2,
	LCD_ARCH_STATUS_CR3_ACCESS = 3,
141
};
142

Charlie Jacobsen's avatar
Charlie Jacobsen committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
/**
 * 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);


161
#endif  /* LCD_DOMAINS_ARCH_H */