]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Allow index-based guest register access without type casts
authorJan Kiszka <jan.kiszka@siemens.com>
Fri, 3 Apr 2015 17:21:32 +0000 (19:21 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 10 Apr 2015 07:00:52 +0000 (09:00 +0200)
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.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/apic.c
hypervisor/arch/x86/i8042.c
hypervisor/arch/x86/include/asm/apic.h
hypervisor/arch/x86/include/asm/i8042.h
hypervisor/arch/x86/include/asm/pci.h
hypervisor/arch/x86/include/asm/processor.h
hypervisor/arch/x86/include/asm/vcpu.h
hypervisor/arch/x86/pci.c
hypervisor/arch/x86/svm.c
hypervisor/arch/x86/vcpu.c
hypervisor/arch/x86/vmx.c

index ac06fb354a0f2f91a8c080042818c90f2dd1b680..a755f956edf30beba026a998a2c22fb7717b5786 100644 (file)
@@ -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;
 
index cabed534120df3108744f689751559012cde55af..d6b335602058b34fdabc61c7e47f6f2fd37cecc8 100644 (file)
@@ -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;
index e8eea68d6c1241abce5e35a7f8cc1eaf9d9cff3a..28779cad47fbbdd33bc908ec9599a968f9d28660 100644 (file)
@@ -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);
 
index 9fb5e2716963c2a5754ef02061b3d60ea9192810..9d25deff9bdaedcfc619efbb1c979e3f6b46f4ad 100644 (file)
@@ -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 */
index b9aeca13b3b5b12848c116942aac626c907e84fd..37ee686ffeab4bbaddd654f7f10636c88535e7bd 100644 (file)
@@ -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);
 
 /** @} */
index 22ca32b4bf454116cba9cdf7fe727b407a8f15cf..1dd6b7d335ebd4580edb5ce917f7a336ac5f31df 100644 (file)
  * @{
  */
 
-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);
 }
index 6a5f5d3064f1fc20c897eac65c5f1bc6c286c6a0..8dd048ffa80e5479e50f25f082583a7636a84ec9 100644 (file)
@@ -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
index 7bbf96c7e99ea549faf7bfaac4f62c3fecedd99e..af48c493bf9a0f486da7698b84f139e816344f5d 100644 (file)
@@ -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;
index 8e5152d7dd0428d85cb57c1e862e3032b503f1a4..ef7773a51872691082c288db6eb0d76d0499d984 100644 (file)
@@ -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;
index c9893e85ebe4088d511a08588febb465f92aa2ee..49324b0af692270b5af65a79151c8497d0adf488 100644 (file)
@@ -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();
 
index cc8582b77779349aa7d9c2959789cac6388e067e..b8e8c19ee3223a875bbcfd00c9c5b8a329331433 100644 (file)
@@ -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;