return true;
}
-unsigned int apic_mmio_access(struct registers *guest_regs,
+unsigned int apic_mmio_access(union registers *guest_regs,
struct per_cpu *cpu_data, unsigned long rip,
const struct guest_paging_structures *pg_structs,
unsigned int reg, bool is_write)
return 0;
}
if (is_write) {
- val = ((unsigned long *)guest_regs)[inst.reg_num];
+ val = guest_regs->by_index[inst.reg_num];
if (apic_accessing_reserved_bits(reg, val))
return 0;
apic_ops.write(reg, val);
} else {
val = apic_ops.read(reg);
- ((unsigned long *)guest_regs)[inst.reg_num] = val;
+ guest_regs->by_index[inst.reg_num] = val;
}
return inst.inst_len;
}
-bool x2apic_handle_write(struct registers *guest_regs,
- struct per_cpu *cpu_data)
+bool x2apic_handle_write(union registers *guest_regs, struct per_cpu *cpu_data)
{
u32 reg = guest_regs->rcx - MSR_X2APIC_BASE;
u32 val = guest_regs->rax;
}
/* must only be called for readable registers */
-void x2apic_handle_read(struct registers *guest_regs)
+void x2apic_handle_read(union registers *guest_regs)
{
u32 reg = guest_regs->rcx - MSR_X2APIC_BASE;
#include <jailhouse/cell-config.h>
-int i8042_access_handler(struct registers *guest_regs, u16 port, bool dir_in,
+int i8042_access_handler(union registers *guest_regs, u16 port, bool dir_in,
unsigned int size)
{
const struct jailhouse_cell_desc *config = this_cell()->config;
void apic_irq_handler(void);
-unsigned int apic_mmio_access(struct registers *guest_regs,
+unsigned int apic_mmio_access(union registers *guest_regs,
struct per_cpu *cpu_data, unsigned long rip,
const struct guest_paging_structures *pg_structs,
unsigned int reg, bool is_write);
-bool x2apic_handle_write(struct registers *guest_regs,
+bool x2apic_handle_write(union registers *guest_regs,
struct per_cpu *cpu_data);
-void x2apic_handle_read(struct registers *guest_regs);
+void x2apic_handle_read(union registers *guest_regs);
u32 x2apic_filter_logical_dest(struct cell *cell, u32 destination);
# define I8042_CMD_WRITE_CTRL_PORT 0xd1
# define I8042_CMD_PULSE_CTRL_PORT 0xf0
-int i8042_access_handler(struct registers *guest_regs, u16 port, bool dir_in,
+int i8042_access_handler(union registers *guest_regs, u16 port, bool dir_in,
unsigned int size);
#endif /* !_JAILHOUSE_ASM_I8042_H */
* @{
*/
-int x86_pci_config_handler(struct registers *guest_regs, struct cell *cell,
+int x86_pci_config_handler(union registers *guest_regs, struct cell *cell,
u16 port, bool dir_in, unsigned int size);
/** @} */
* @{
*/
-struct registers {
- unsigned long r15;
- unsigned long r14;
- unsigned long r13;
- unsigned long r12;
- unsigned long r11;
- unsigned long r10;
- unsigned long r9;
- unsigned long r8;
- unsigned long rdi;
- unsigned long rsi;
- unsigned long rbp;
- unsigned long unused;
- unsigned long rbx;
- unsigned long rdx;
- unsigned long rcx;
- unsigned long rax;
+union registers {
+ struct {
+ unsigned long r15;
+ unsigned long r14;
+ unsigned long r13;
+ unsigned long r12;
+ unsigned long r11;
+ unsigned long r10;
+ unsigned long r9;
+ unsigned long r8;
+ unsigned long rdi;
+ unsigned long rsi;
+ unsigned long rbp;
+ unsigned long unused;
+ unsigned long rbx;
+ unsigned long rdx;
+ unsigned long rcx;
+ unsigned long rax;
+ };
+ unsigned long by_index[16];
};
struct desc_table_reg {
: "memory");
}
-static inline void set_rdmsr_value(struct registers *regs, unsigned long val)
+static inline void set_rdmsr_value(union registers *regs, unsigned long val)
{
regs->rax = (u32)val;
regs->rdx = val >> 32;
}
-static inline unsigned long get_wrmsr_value(struct registers *regs)
+static inline unsigned long get_wrmsr_value(union registers *regs)
{
return (u32)regs->rax | (regs->rdx << 32);
}
void __attribute__((noreturn)) vcpu_activate_vmm(struct per_cpu *cpu_data);
void __attribute__((noreturn))
-vcpu_deactivate_vmm(struct registers *guest_regs);
+vcpu_deactivate_vmm(union registers *guest_regs);
-void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data);
+void vcpu_handle_exit(union registers *guest_regs, struct per_cpu *cpu_data);
void vcpu_park(void);
void vcpu_vendor_set_guest_pat(unsigned long val);
-void vcpu_handle_hypercall(struct registers *guest_regs);
+void vcpu_handle_hypercall(union registers *guest_regs);
-bool vcpu_handle_io_access(struct registers *guest_regs);
-bool vcpu_handle_mmio_access(struct registers *guest_regs);
+bool vcpu_handle_io_access(union registers *guest_regs);
+bool vcpu_handle_mmio_access(union registers *guest_regs);
-bool vcpu_handle_msr_read(struct registers *guest_regs);
-bool vcpu_handle_msr_write(struct registers *guest_regs);
+bool vcpu_handle_msr_read(union registers *guest_regs);
+bool vcpu_handle_msr_write(union registers *guest_regs);
-bool vcpu_handle_xsetbv(struct registers *guest_regs);
+bool vcpu_handle_xsetbv(union registers *guest_regs);
-void vcpu_reset(struct registers *guest_regs);
+void vcpu_reset(union registers *guest_regs);
#endif
*
* @private
*/
-static void set_rax_reg(struct registers *guest_regs,
+static void set_rax_reg(union registers *guest_regs,
u32 value_new, u8 size)
{
u64 value_old = guest_regs->rax;
*
* @private
*/
-static u32 get_rax_reg(struct registers *guest_regs, u8 size)
+static u32 get_rax_reg(union registers *guest_regs, u8 size)
{
return guest_regs->rax & BYTE_MASK(size);
}
* @private
*/
static int
-data_port_in_handler(struct registers *guest_regs, struct pci_device *device,
+data_port_in_handler(union registers *guest_regs, struct pci_device *device,
u16 address, unsigned int size)
{
u32 reg_data;
* @private
*/
static int
-data_port_out_handler(struct registers *guest_regs, struct pci_device *device,
+data_port_out_handler(union registers *guest_regs, struct pci_device *device,
u16 address, unsigned int size)
{
u32 reg_data = get_rax_reg(guest_regs, size);
*
* @return 1 if handled successfully, 0 if unhandled, -1 on access error.
*/
-int x86_pci_config_handler(struct registers *guest_regs, struct cell *cell,
+int x86_pci_config_handler(union registers *guest_regs, struct cell *cell,
u16 port, bool dir_in, unsigned int size)
{
struct pci_device *device;
}
void __attribute__((noreturn))
-vcpu_deactivate_vmm(struct registers *guest_regs)
+vcpu_deactivate_vmm(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
struct vmcb *vmcb = &cpu_data->vmcb;
* result in no more than VMEXIT_INVALID. Maybe we can get along without it
* altogether?
*/
-static bool svm_handle_cr(struct registers *guest_regs,
+static bool svm_handle_cr(union registers *guest_regs,
struct per_cpu *cpu_data)
{
struct vmcb *vmcb = &cpu_data->vmcb;
if (reg == 4)
val = vmcb->rsp;
else
- val = ((unsigned long *)guest_regs)[15 - reg];
+ val = guest_regs->by_index[15 - reg];
vcpu_skip_emulated_instruction(X86_INST_LEN_MOV_TO_CR);
/* Flush TLB on PG/WP/CD/NW change: See APMv2, Sect. 15.16 */
return ok;
}
-static bool svm_handle_msr_write(struct registers *guest_regs,
+static bool svm_handle_msr_write(union registers *guest_regs,
struct per_cpu *cpu_data)
{
struct vmcb *vmcb = &cpu_data->vmcb;
* TODO: This handles unaccelerated (non-AVIC) access. AVIC should
* be treated separately in svm_handle_avic_access().
*/
-static bool svm_handle_apic_access(struct registers *guest_regs,
+static bool svm_handle_apic_access(union registers *guest_regs,
struct per_cpu *cpu_data)
{
struct vmcb *vmcb = &cpu_data->vmcb;
return false;
}
-static void dump_guest_regs(struct registers *guest_regs, struct vmcb *vmcb)
+static void dump_guest_regs(union registers *guest_regs, struct vmcb *vmcb)
{
panic_printk("RIP: %p RSP: %p FLAGS: %x\n", vmcb->rip,
vmcb->rsp, vmcb->rflags);
mmio->is_write = !!(vmcb->exitinfo1 & 0x2);
}
-void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
+void vcpu_handle_exit(union registers *guest_regs, struct per_cpu *cpu_data)
{
struct vmcb *vmcb = &cpu_data->vmcb;
bool res = false;
vcpu_vendor_cell_exit(cell);
}
-void vcpu_handle_hypercall(struct registers *guest_regs)
+void vcpu_handle_hypercall(union registers *guest_regs)
{
unsigned long code = guest_regs->rax;
struct vcpu_execution_state x_state;
vcpu_deactivate_vmm(guest_regs);
}
-bool vcpu_handle_io_access(struct registers *guest_regs)
+bool vcpu_handle_io_access(union registers *guest_regs)
{
struct vcpu_io_intercept io;
int result = 0;
return false;
}
-bool vcpu_handle_mmio_access(struct registers *guest_regs)
+bool vcpu_handle_mmio_access(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
struct guest_paging_structures pg_structs;
goto invalid_access;
if (mmio.is_write)
- val = ((unsigned long *)guest_regs)[inst.reg_num];
+ val = guest_regs->by_index[inst.reg_num];
result = ioapic_access_handler(cpu_data->cell, mmio.is_write,
mmio.phys_addr, &val);
if (result == 1) {
if (!mmio.is_write)
- ((unsigned long *)guest_regs)[inst.reg_num] = val;
+ guest_regs->by_index[inst.reg_num] = val;
vcpu_skip_emulated_instruction(inst.inst_len);
return true;
}
return false;
}
-bool vcpu_handle_msr_read(struct registers *guest_regs)
+bool vcpu_handle_msr_read(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
return true;
}
-bool vcpu_handle_msr_write(struct registers *guest_regs)
+bool vcpu_handle_msr_write(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
unsigned int bit_pos, pa;
return true;
}
-bool vcpu_handle_xsetbv(struct registers *guest_regs)
+bool vcpu_handle_xsetbv(union registers *guest_regs)
{
this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_XSETBV]++;
return false;
}
-void vcpu_reset(struct registers *guest_regs)
+void vcpu_reset(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
}
void __attribute__((noreturn))
-vcpu_deactivate_vmm(struct registers *guest_regs)
+vcpu_deactivate_vmm(union registers *guest_regs)
{
unsigned long *stack = (unsigned long *)vmcs_read64(GUEST_RSP);
unsigned long linux_ip = vmcs_read64(GUEST_RIP);
vmcs_read32(VM_ENTRY_CONTROLS) | VM_ENTRY_IA32E_MODE);
}
-static bool vmx_handle_cr(struct registers *guest_regs,
+static bool vmx_handle_cr(union registers *guest_regs,
struct per_cpu *cpu_data)
{
u64 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
if (reg == 4)
val = vmcs_read64(GUEST_RSP);
else
- val = ((unsigned long *)guest_regs)[15 - reg];
+ val = guest_regs->by_index[15 - reg];
if (cr == 0 || cr == 4) {
vcpu_skip_emulated_instruction(X86_INST_LEN_MOV_TO_CR);
vmcs_write64(GUEST_IA32_PAT, val);
}
-static bool vmx_handle_apic_access(struct registers *guest_regs,
+static bool vmx_handle_apic_access(union registers *guest_regs,
struct per_cpu *cpu_data)
{
struct guest_paging_structures pg_structs;
vmcs_read64(GUEST_LINEAR_ADDRESS));
}
-static void dump_guest_regs(struct registers *guest_regs)
+static void dump_guest_regs(union registers *guest_regs)
{
panic_printk("RIP: %p RSP: %p FLAGS: %x\n", vmcs_read64(GUEST_RIP),
vmcs_read64(GUEST_RSP), vmcs_read64(GUEST_RFLAGS));
mmio->is_write = !!(exitq & 0x2);
}
-void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
+void vcpu_handle_exit(union registers *guest_regs, struct per_cpu *cpu_data)
{
u32 reason = vmcs_read32(VM_EXIT_REASON);
int sipi_vector;