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) &&
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,
}
}
-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;
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;
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;
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;
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:
}
}
-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;
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");
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);