]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: Generic hypercall dispatching
authorJan Kiszka <jan.kiszka@siemens.com>
Sat, 12 Apr 2014 06:14:16 +0000 (08:14 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 2 May 2014 06:43:59 +0000 (08:43 +0200)
Move the switch-case part of vmx_handle_hypercall into a generic
hypercall dispatcher.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/vmx.c
hypervisor/control.c
hypervisor/include/jailhouse/control.h

index 60a37cd00d2478e80b873657c68dd2c9af787c4a..f0c5cb9186414ab536fd06d726ba413accb92737 100644 (file)
@@ -858,6 +858,8 @@ static void update_efer(void)
 static void vmx_handle_hypercall(struct registers *guest_regs,
                                 struct per_cpu *cpu_data)
 {
+       unsigned long code = guest_regs->rax;
+
        vmx_skip_emulated_instruction(X86_INST_LEN_VMCALL);
 
        if ((!(vmcs_read64(GUEST_IA32_EFER) & EFER_LMA) &&
@@ -867,35 +869,14 @@ static void vmx_handle_hypercall(struct registers *guest_regs,
                return;
        }
 
-       switch (guest_regs->rax) {
-       case JAILHOUSE_HC_DISABLE:
-               guest_regs->rax = shutdown(cpu_data);
-               if (guest_regs->rax == 0)
-                       vmx_cpu_deactivate_vmm(guest_regs, cpu_data);
-               break;
-       case JAILHOUSE_HC_CELL_CREATE:
-               guest_regs->rax = cell_create(cpu_data, guest_regs->rdi);
-               break;
-       case JAILHOUSE_HC_CELL_DESTROY:
-               guest_regs->rax = cell_destroy(cpu_data, guest_regs->rdi);
-               break;
-       case JAILHOUSE_HC_HYPERVISOR_GET_INFO:
-               guest_regs->rax = hypervisor_get_info(cpu_data,
-                                                     guest_regs->rdi);
-               break;
-       case JAILHOUSE_HC_CELL_GET_STATE:
-               guest_regs->rax = cell_get_state(cpu_data, guest_regs->rdi);
-               break;
-       case JAILHOUSE_HC_CPU_GET_STATE:
-               guest_regs->rax = cpu_get_state(cpu_data, guest_regs->rdi);
-               break;
-       default:
+       guest_regs->rax = hypercall(cpu_data, code, guest_regs->rdi);
+       if (guest_regs->rax == -ENOSYS)
                printk("CPU %d: Unknown vmcall %d, RIP: %p\n",
-                      cpu_data->cpu_id, guest_regs->rax,
+                      cpu_data->cpu_id, code,
                       vmcs_read64(GUEST_RIP) - X86_INST_LEN_VMCALL);
-               guest_regs->rax = -ENOSYS;
-               break;
-       }
+
+       if (code == JAILHOUSE_HC_DISABLE && guest_regs->rax == 0)
+               vmx_cpu_deactivate_vmm(guest_regs, cpu_data);
 }
 
 static bool vmx_handle_cr(struct registers *guest_regs,
index ebc3dd954ee023ef0f189c706542a5eed6533aa8..92382ece8c6bdad29b5c55b58f5c1f24591039b4 100644 (file)
@@ -173,7 +173,7 @@ static void remap_to_root_cell(const struct jailhouse_memory *mem)
        }
 }
 
-int cell_create(struct per_cpu *cpu_data, unsigned long config_address)
+static int cell_create(struct per_cpu *cpu_data, unsigned long config_address)
 {
        unsigned long mapping_addr = TEMPORARY_MAPPING_CPU_BASE(cpu_data);
        unsigned long cfg_page_offs = config_address & ~PAGE_MASK;
@@ -349,7 +349,7 @@ static bool cell_shutdown_ok(struct cell *cell)
        return false;
 }
 
-int cell_destroy(struct per_cpu *cpu_data, unsigned long id)
+static int cell_destroy(struct per_cpu *cpu_data, unsigned long id)
 {
        const struct jailhouse_memory *mem;
        struct cell *cell, *previous;
@@ -422,7 +422,7 @@ resume_out:
        return err;
 }
 
-int cell_get_state(struct per_cpu *cpu_data, unsigned long id)
+static int cell_get_state(struct per_cpu *cpu_data, unsigned long id)
 {
        struct cell *cell;
 
@@ -450,7 +450,7 @@ int cell_get_state(struct per_cpu *cpu_data, unsigned long id)
        return -ENOENT;
 }
 
-int shutdown(struct per_cpu *cpu_data)
+static int shutdown(struct per_cpu *cpu_data)
 {
        unsigned int this_cpu = cpu_data->cpu_id;
        struct cell *cell;
@@ -505,7 +505,7 @@ int shutdown(struct per_cpu *cpu_data)
        return ret;
 }
 
-long hypervisor_get_info(struct per_cpu *cpu_data, unsigned long type)
+static long hypervisor_get_info(struct per_cpu *cpu_data, unsigned long type)
 {
        switch (type) {
        case JAILHOUSE_INFO_MEM_POOL_SIZE:
@@ -523,7 +523,7 @@ long hypervisor_get_info(struct per_cpu *cpu_data, unsigned long type)
        }
 }
 
-int cpu_get_state(struct per_cpu *cpu_data, unsigned long cpu_id)
+static int cpu_get_state(struct per_cpu *cpu_data, unsigned long cpu_id)
 {
        if (!cpu_id_valid(cpu_id))
                return -EINVAL;
@@ -542,6 +542,26 @@ int cpu_get_state(struct per_cpu *cpu_data, unsigned long cpu_id)
                JAILHOUSE_CPU_RUNNING;
 }
 
+long hypercall(struct per_cpu *cpu_data, unsigned long code, unsigned long arg)
+{
+       switch (code) {
+       case JAILHOUSE_HC_DISABLE:
+               return shutdown(cpu_data);
+       case JAILHOUSE_HC_CELL_CREATE:
+               return cell_create(cpu_data, arg);
+       case JAILHOUSE_HC_CELL_DESTROY:
+               return cell_destroy(cpu_data, arg);
+       case JAILHOUSE_HC_HYPERVISOR_GET_INFO:
+               return hypervisor_get_info(cpu_data, arg);
+       case JAILHOUSE_HC_CELL_GET_STATE:
+               return cell_get_state(cpu_data, arg);
+       case JAILHOUSE_HC_CPU_GET_STATE:
+               return cpu_get_state(cpu_data, arg);
+       default:
+               return -ENOSYS;
+       }
+}
+
 void panic_stop(struct per_cpu *cpu_data)
 {
        panic_printk("Stopping CPU");
index 9181f87682940c66120010b4ed8570f0eb7dd570..b2c68a9ea4b22a9ee50a67a92c8c6abcc96f863b 100644 (file)
@@ -39,15 +39,8 @@ bool cpu_id_valid(unsigned long cpu_id);
 int check_mem_regions(const struct jailhouse_cell_desc *config);
 int cell_init(struct cell *cell, bool copy_cpu_set);
 
-int cell_create(struct per_cpu *cpu_data, unsigned long config_address);
-int cell_destroy(struct per_cpu *cpu_data, unsigned long id);
-int cell_get_state(struct per_cpu *cpu_data, unsigned long id);
-
-int shutdown(struct per_cpu *cpu_data);
-
-long hypervisor_get_info(struct per_cpu *cpu_data, unsigned long type);
-
-int cpu_get_state(struct per_cpu *cpu_data, unsigned long id);
+long hypercall(struct per_cpu *cpu_data, unsigned long code,
+              unsigned long arg);
 
 void __attribute__((noreturn)) panic_stop(struct per_cpu *cpu_data);
 void panic_halt(struct per_cpu *cpu_data);