Commit c37435a0 authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

Simple EPT fault handling code in place (untested).

Removed the `auto' memory alloc and map from the
original handler. The new handler is simple for now;
it just reads the guest virtual and physical addresses
involved in the fault. The arch-indepent code will be
responsible for deciding what to do.
parent 1abf5ea6
......@@ -51,8 +51,10 @@ struct lcd_arch {
/*
* Public Data
*/
u64 page_fault_addr;
struct {
u64 gva;
u64 gpa;
} run_info;
/*
* Private Data
......@@ -127,6 +129,7 @@ int lcd_arch_run(struct lcd_arch *vcpu);
enum lcd_arch_status {
LCD_ARCH_STATUS_PAGE_FAULT = 0,
LCD_ARCH_STATUS_EXT_INTR = 1,
LCD_ARCH_STATUS_EPT_FAULT = 2,
};
#endif /* LCD_DOMAINS_ARCH_H */
......@@ -1596,7 +1596,7 @@ static void vmx_handle_vmcall(struct lcd_arch *vcpu)
* to be *enabled*, but will be disabled when the interrupt
* handler is called, per the ia32 spec (Intel SDM V3 6.8.1).
*/
static void vmx_handle_external_intr(struct lcd_arch *vcpu)
static int vmx_handle_external_intr(struct lcd_arch *vcpu)
{
unsigned int vector;
unsigned long entry;
......@@ -1669,6 +1669,7 @@ static void vmx_handle_external_intr(struct lcd_arch *vcpu)
[ss]"i"(__KERNEL_DS),
[cs]"i"(__KERNEL_CS)
);
return LCD_ARCH_STATUS_EXT_INTR;
}
/**
......@@ -1689,7 +1690,7 @@ static int vmx_handle_hard_exception(struct lcd_arch *vcpu)
*
* Set page fault address, and return status code.
*/
vcpu->page_fault_addr = vcpu->exit_qualification;
vcpu->run_info.gva = vcpu->exit_qualification;
return LCD_ARCH_STATUS_PAGE_FAULT;
default:
printk(KERN_ERR "lcd vmx: unhandled hw exception:\n");
......@@ -1724,10 +1725,14 @@ static int vmx_handle_exception_nmi(struct lcd_arch *vcpu)
}
}
static void vmx_handle_ept(struct lcd_arch *vcpu)
static int vmx_handle_ept(struct lcd_arch *vcpu)
{
/*
* Intel SDM V3 27.2.1
*/
vcpu->run_info.gva = vmcs_readl(GUEST_LINEAR_ADDRESS);
vcpu->run_info.gpa = vmcs_readl(GUEST_PHYSICAL_ADDRESS);
return LCD_ARCH_STATUS_EPT_FAULT;
}
static void vmx_handle_control_reg(struct lcd_arch *vcpu)
......@@ -1925,14 +1930,13 @@ int lcd_arch_run(struct lcd_arch *vcpu)
ret = vmx_handle_exception_nmi(vcpu);
break;
case EXIT_REASON_EXTERNAL_INTERRUPT:
vmx_handle_external_int(vcpu);
ret = LCD_ARCH_STATUS_EXT_INTR;
ret = vmx_handle_external_int(vcpu);
break;
case EXIT_REASON_VMCALL:
vmx_handle_vmcall(vcpu);
break;
case EXIT_REASON_EPT_VIOLATION:
vmx_handle_ept(vcpu);
ret = vmx_handle_ept(vcpu);
break;
case EXIT_REASON_CR_ACCESS:
vmx_handle_control_reg(vcpu);
......
......@@ -2178,71 +2178,71 @@ int lcd_find_hva_by_gpa(struct lcd *lcd, u64 gpa, u64 *hva) {
}
EXPORT_SYMBOL(lcd_find_hva_by_gpa);
static void vmx_handle_external_interrupt(struct lcd *lcd) {
if ((lcd->exit_intr_info &
(INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK))
== (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) {
unsigned int vector;
unsigned long entry;
gate_desc *desc;
unsigned long tmp;
/* static void vmx_handle_external_interrupt(struct lcd *lcd) { */
/* if ((lcd->exit_intr_info & */
/* (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK)) */
/* == (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) { */
/* unsigned int vector; */
/* unsigned long entry; */
/* gate_desc *desc; */
/* unsigned long tmp; */
vector = lcd->vec_no;
desc = (gate_desc *)lcd->host_idt_base + vector;
entry = gate_offset(*desc);
asm volatile(
"mov %%" _ASM_SP ", %[sp]\n\t"
"and $0xfffffffffffffff0, %%" _ASM_SP "\n\t"
"push $%c[ss]\n\t"
"push %[sp]\n\t"
"pushf\n\t"
"orl $0x200, (%%" _ASM_SP ")\n\t"
__ASM_SIZE(push) " $%c[cs]\n\t"
"call *%[entry]\n\t"
:
[sp]"=&r"(tmp)
:
[entry]"r"(entry),
[ss]"i"(__KERNEL_DS),
[cs]"i"(__KERNEL_CS)
);
/* printk("lcd: handling external %u\n", vector); */
if (irqs_disabled())
local_irq_enable();
} else {
local_irq_enable();
/* printk("lcd: not handling external %u\n", lcd->exit_intr_info); */
}
}
/* vector = lcd->vec_no; */
/* desc = (gate_desc *)lcd->host_idt_base + vector; */
/* entry = gate_offset(*desc); */
/* asm volatile( */
/* "mov %%" _ASM_SP ", %[sp]\n\t" */
/* "and $0xfffffffffffffff0, %%" _ASM_SP "\n\t" */
/* "push $%c[ss]\n\t" */
/* "push %[sp]\n\t" */
/* "pushf\n\t" */
/* "orl $0x200, (%%" _ASM_SP ")\n\t" */
/* __ASM_SIZE(push) " $%c[cs]\n\t" */
/* "call *%[entry]\n\t" */
/* : */
/* [sp]"=&r"(tmp) */
/* : */
/* [entry]"r"(entry), */
/* [ss]"i"(__KERNEL_DS), */
/* [cs]"i"(__KERNEL_CS) */
/* ); */
/* /\* printk("lcd: handling external %u\n", vector); *\/ */
/* if (irqs_disabled()) */
/* local_irq_enable(); */
/* } else { */
/* local_irq_enable(); */
/* /\* printk("lcd: not handling external %u\n", lcd->exit_intr_info); *\/ */
/* } */
/* } */
static void vmx_handle_vmcall(struct lcd *lcd) {
u32 ipc_dir, ipc_peer;
/* static void vmx_handle_vmcall(struct lcd *lcd) { */
/* u32 ipc_dir, ipc_peer; */
//printk(KERN_ERR "%c", lcd->regs[VCPU_REGS_RAX]);
printk(KERN_ERR "%016llx", lcd->regs[VCPU_REGS_RAX]);
ipc_dir = LCD_IPC_DIR(lcd->regs[VCPU_REGS_RAX]);
ipc_peer = LCD_IPC_PEER(lcd->regs[VCPU_REGS_RAX]);
printk(KERN_ERR "vmx_handle_vmcall - dir %d peer %d\n", ipc_dir, ipc_peer);
switch(ipc_dir) {
case IPC_SEND:
ipc_send(lcd->sync_ipc.my_capid, ipc_peer);
break;
case IPC_RECV:
ipc_recv(lcd->sync_ipc.my_capid, ipc_peer);
break;
}
#if 0
//printk(KERN_ERR "lcd_run: got vmcall %llu and %c\n", lcd->regs[VCPU_REGS_RAX], lcd->regs[VCPU_REGS_RAX]);
if (lcd->regs[VCPU_REGS_RAX] == 0xdeadbeef) {
display_mr((utcb_t *)lcd->shared);
return;
}
#endif
/* //printk(KERN_ERR "%c", lcd->regs[VCPU_REGS_RAX]); */
/* printk(KERN_ERR "%016llx", lcd->regs[VCPU_REGS_RAX]); */
/* ipc_dir = LCD_IPC_DIR(lcd->regs[VCPU_REGS_RAX]); */
/* ipc_peer = LCD_IPC_PEER(lcd->regs[VCPU_REGS_RAX]); */
/* printk(KERN_ERR "vmx_handle_vmcall - dir %d peer %d\n", ipc_dir, ipc_peer); */
/* switch(ipc_dir) { */
/* case IPC_SEND: */
/* ipc_send(lcd->sync_ipc.my_capid, ipc_peer); */
/* break; */
/* case IPC_RECV: */
/* ipc_recv(lcd->sync_ipc.my_capid, ipc_peer); */
/* break; */
/* } */
/* #if 0 */
/* //printk(KERN_ERR "lcd_run: got vmcall %llu and %c\n", lcd->regs[VCPU_REGS_RAX], lcd->regs[VCPU_REGS_RAX]); */
/* if (lcd->regs[VCPU_REGS_RAX] == 0xdeadbeef) { */
/* display_mr((utcb_t *)lcd->shared); */
/* return; */
/* } */
/* #endif */
}
/* } */
/* static void vmx_handle_page_fault(struct lcd *lcd) { */
/* printk(KERN_INFO "lcd: page fault VA %p\n", */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment