Convert struct registers into a union and provide a by_index array for
index-based access. This is used by various handlers that parse guest
instructions and so far use a blunt type case on the structure.
hypervisor/arch/x86/apic.c | 11 ++++----
hypervisor/arch/x86/i8042.c | 2 +-
hypervisor/arch/x86/include/asm/apic.h | 6 ++---
hypervisor/arch/x86/include/asm/i8042.h | 2 +-
hypervisor/arch/x86/include/asm/pci.h | 2 +-
hypervisor/arch/x86/include/asm/processor.h | 41 ++++++++++++++++-------------
hypervisor/arch/x86/include/asm/vcpu.h | 18 ++++++-------
hypervisor/arch/x86/pci.c | 10 +++----
hypervisor/arch/x86/svm.c | 14 +++++-----
hypervisor/arch/x86/vcpu.c | 18 ++++++-------
hypervisor/arch/x86/vmx.c | 12 ++++-----
11 files changed, 69 insertions(+), 67 deletions(-)
diff --git a/hypervisor/arch/x86/apic.c b/hypervisor/arch/x86/apic.c
index ac06fb3..a755f95 100644
--- a/hypervisor/arch/x86/apic.c
+++ b/hypervisor/arch/x86/apic.c
@@ -468,7 +468,7 @@ static bool apic_invalid_lvt_delivery_mode(unsigned int reg, u32 val)
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)
@@ -485,7 +485,7 @@ unsigned int apic_mmio_access(struct registers *guest_regs,
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;
@@ -512,13 +512,12 @@ unsigned int apic_mmio_access(struct registers *guest_regs,
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;
@@ -540,7 +539,7 @@ bool x2apic_handle_write(struct registers *guest_regs,
}
/* 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;
diff --git a/hypervisor/arch/x86/i8042.c b/hypervisor/arch/x86/i8042.c
index cabed53..d6b3356 100644
--- a/hypervisor/arch/x86/i8042.c
+++ b/hypervisor/arch/x86/i8042.c
@@ -18,7 +18,7 @@
#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;
diff --git a/hypervisor/arch/x86/include/asm/apic.h b/hypervisor/arch/x86/include/asm/apic.h
index e8eea68..28779ca 100644
--- a/hypervisor/arch/x86/include/asm/apic.h
+++ b/hypervisor/arch/x86/include/asm/apic.h
@@ -161,14 +161,14 @@ void apic_send_irq(struct apic_irq_message irq_msg);
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);
diff --git a/hypervisor/arch/x86/include/asm/i8042.h b/hypervisor/arch/x86/include/asm/i8042.h
index 9fb5e27..9d25def 100644
--- a/hypervisor/arch/x86/include/asm/i8042.h
+++ b/hypervisor/arch/x86/include/asm/i8042.h
@@ -19,7 +19,7 @@
# 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 */
diff --git a/hypervisor/arch/x86/include/asm/pci.h b/hypervisor/arch/x86/include/asm/pci.h
index b9aeca1..37ee686 100644
--- a/hypervisor/arch/x86/include/asm/pci.h
+++ b/hypervisor/arch/x86/include/asm/pci.h
@@ -32,7 +32,7 @@
* @{
*/
-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);
/** @} */
diff --git a/hypervisor/arch/x86/include/asm/processor.h b/hypervisor/arch/x86/include/asm/processor.h
index 22ca32b..1dd6b7d 100644
--- a/hypervisor/arch/x86/include/asm/processor.h
+++ b/hypervisor/arch/x86/include/asm/processor.h
@@ -138,23 +138,26 @@
* @{
*/
-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 {
@@ -275,13 +278,13 @@ static inline void write_msr(unsigned int msr, unsigned long val)
: "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);
}
diff --git a/hypervisor/arch/x86/include/asm/vcpu.h b/hypervisor/arch/x86/include/asm/vcpu.h
index 6a5f5d3..8dd048f 100644
--- a/hypervisor/arch/x86/include/asm/vcpu.h
+++ b/hypervisor/arch/x86/include/asm/vcpu.h
@@ -68,9 +68,9 @@ void vcpu_exit(struct per_cpu *cpu_data);
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);
@@ -106,16 +106,16 @@ bool vcpu_get_guest_paging_structs(struct guest_paging_structures *pg_structs);
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
diff --git a/hypervisor/arch/x86/pci.c b/hypervisor/arch/x86/pci.c
index 7bbf96c..af48c49 100644
--- a/hypervisor/arch/x86/pci.c
+++ b/hypervisor/arch/x86/pci.c
@@ -71,7 +71,7 @@ void arch_pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size)
*
* @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;
@@ -91,7 +91,7 @@ static void set_rax_reg(struct registers *guest_regs,
*
* @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);
}
@@ -108,7 +108,7 @@ static u32 get_rax_reg(struct registers *guest_regs, u8 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;
@@ -135,7 +135,7 @@ data_port_in_handler(struct registers *guest_regs, struct pci_device *device,
* @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);
@@ -160,7 +160,7 @@ data_port_out_handler(struct registers *guest_regs, struct pci_device *device,
*
* @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;
diff --git a/hypervisor/arch/x86/svm.c b/hypervisor/arch/x86/svm.c
index 8e5152d..ef7773a 100644
--- a/hypervisor/arch/x86/svm.c
+++ b/hypervisor/arch/x86/svm.c
@@ -469,7 +469,7 @@ 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)
{
struct per_cpu *cpu_data = this_cpu_data();
struct vmcb *vmcb = &cpu_data->vmcb;
@@ -778,7 +778,7 @@ out:
* 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;
@@ -804,7 +804,7 @@ static bool svm_handle_cr(struct registers *guest_regs,
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 */
@@ -821,7 +821,7 @@ out:
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;
@@ -846,7 +846,7 @@ static bool svm_handle_msr_write(struct registers *guest_regs,
* 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;
@@ -878,7 +878,7 @@ out_err:
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);
@@ -915,7 +915,7 @@ void vcpu_vendor_get_mmio_intercept(struct vcpu_mmio_intercept *mmio)
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;
diff --git a/hypervisor/arch/x86/vcpu.c b/hypervisor/arch/x86/vcpu.c
index c9893e8..49324b0 100644
--- a/hypervisor/arch/x86/vcpu.c
+++ b/hypervisor/arch/x86/vcpu.c
@@ -133,7 +133,7 @@ void vcpu_cell_exit(struct cell *cell)
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;
@@ -164,7 +164,7 @@ void vcpu_handle_hypercall(struct registers *guest_regs)
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;
@@ -192,7 +192,7 @@ invalid_access:
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;
@@ -213,7 +213,7 @@ bool vcpu_handle_mmio_access(struct registers *guest_regs)
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);
@@ -227,7 +227,7 @@ bool vcpu_handle_mmio_access(struct registers *guest_regs)
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;
}
@@ -240,7 +240,7 @@ invalid_access:
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();
@@ -264,7 +264,7 @@ bool vcpu_handle_msr_read(struct registers *guest_regs)
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;
@@ -311,7 +311,7 @@ bool vcpu_handle_msr_write(struct registers *guest_regs)
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]++;
@@ -331,7 +331,7 @@ bool vcpu_handle_xsetbv(struct registers *guest_regs)
return false;
}
-void vcpu_reset(struct registers *guest_regs)
+void vcpu_reset(union registers *guest_regs)
{
struct per_cpu *cpu_data = this_cpu_data();
diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c
index cc8582b..b8e8c19 100644
--- a/hypervisor/arch/x86/vmx.c
+++ b/hypervisor/arch/x86/vmx.c
@@ -698,7 +698,7 @@ 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)
{
unsigned long *stack = (unsigned long *)vmcs_read64(GUEST_RSP);
unsigned long linux_ip = vmcs_read64(GUEST_RIP);
@@ -893,7 +893,7 @@ static void update_efer(void)
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);
@@ -907,7 +907,7 @@ static bool vmx_handle_cr(struct registers *guest_regs,
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);
@@ -949,7 +949,7 @@ void vcpu_vendor_set_guest_pat(unsigned long val)
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;
@@ -998,7 +998,7 @@ static void dump_vm_exit_details(u32 reason)
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));
@@ -1038,7 +1038,7 @@ void vcpu_vendor_get_mmio_intercept(struct vcpu_mmio_intercept *mmio)
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;
--
2.1.4