...
 
Commits (2)
......@@ -123,7 +123,8 @@ typedef enum {
VMFUNC_TEST_EMPTY_SWITCH = 0x1,
VMFUNC_TEST_DUMMY_CALL = 0x2,
VMFUNC_TEST_RPC_CALL = 0x3,
VMFUNC_TEST_RPC_CALLBACK = 0x4,
VMFUNC_TEST_RPC_CALL_BENCHMARK = 0x4,
VMFUNC_TEST_RPC_CALLBACK = 0x5,
} vmfunc_test_t;
void vmfunc_trampoline_entry(struct fipc_message *msg);
......
......@@ -18,7 +18,7 @@
#include <lcd_domains/microkernel.h>
#include <asm/liblcd/address_spaces.h>
#ifdef CONFIG_MAP_TRACE_BUFFER_BFLANK
#if defined(CONFIG_LCD_TRACE_BUFFER) && defined(CONFIG_MAP_TRACE_BUFFER_BFLANK)
#include <linux/lcd_trace.h>
#endif
......@@ -970,7 +970,7 @@ int lcd_arch_create(struct lcd_arch **out)
for_each_online_cpu(cpu) {
/* Get the EPT VMFUNC switching page for this CPU */
struct page *eptp_list_page = (struct page *) per_cpu(vmfunc_eptp_list_page, cpu);
#ifdef CONFIG_MAP_TRACE_BUFFER_BFLANK
#if defined(CONFIG_LCD_TRACE_BUFFER) && defined(CONFIG_MAP_TRACE_BUFFER_BFLANK)
unsigned char *this_ring_buf = per_cpu(ring_buffer, cpu);
unsigned char this_ring_head = per_cpu(ring_head, cpu);
#endif
......@@ -993,7 +993,7 @@ int lcd_arch_create(struct lcd_arch **out)
/* Add EPT to the VMFUNC switching page */
eptp_list[lcd_arch->ept_id] = eptp;
#ifdef CONFIG_MAP_TRACE_BUFFER_BFLANK
#if defined(CONFIG_LCD_TRACE_BUFFER) && defined(CONFIG_MAP_TRACE_BUFFER_BFLANK)
/* pass GVA of this buffer on idx:3 */
eptp_list[3] = (uint64_t) this_ring_buf;
/* pass num_pages of ring buffer on idx:4 */
......
......@@ -389,7 +389,8 @@ static int isolated_map_vmalloc_mem(struct lcd *lcd,
* Map it in the LCD's guest physical
*/
#ifdef CONFIG_LVD
LCD_MSG("%s gpa: %llx hpa: %llx", __func__, gpa, va2hpa(page_address(p)));
if (0)
LCD_MSG("%s gpa: %llx hpa: %llx", __func__, gpa, va2hpa(page_address(p)));
ret = lcd_arch_ept_map_all_cpus(lcd->lcd_arch,
gpa,
va2hpa(page_address(p)),
......
......@@ -7,12 +7,14 @@
#include <libfipc.h>
#include <linux/kallsyms.h>
#include <asm/pgtable_64.h>
#ifdef CONFIG_LCD_TRACE_BUFFER
#include <linux/lcd_trace.h>
#endif
#define NUM_LCDS 5
/* this is the only function Intel VT-x support */
#define VM_FUNCTION 0
#define NUM_ITERATIONS 1000000
#define NUM_ITERATIONS 10000000
#define CONFIG_VMFUNC_SWITCH_MICROBENCHMARK 1
/* exported by the microkernel. We trust that it's sane */
......@@ -222,11 +224,15 @@ int vmfunc_klcd_wrapper(struct fipc_message *msg, unsigned int ept)
msg->rpc_id,
current->lcd_stack);
#endif
#ifdef CONFIG_LCD_TRACE_BUFFER
add_trace_entry(EVENT_VMFUNC_TRAMP_ENTRY, msg->rpc_id);
#endif
vmfunc_trampoline_entry(msg);
#ifdef CONFIG_LCD_TRACE_BUFFER
add_trace_entry(EVENT_VMFUNC_TRAMP_EXIT, msg->rpc_id);
#endif
local_irq_save(flags);
if (--current->nested_count == 0)
......@@ -241,6 +247,8 @@ exit:
int vmfunc_klcd_test_wrapper(struct fipc_message *msg, unsigned int ept, vmfunc_test_t test)
{
int ret = 0;
unsigned long flags;
if (ept > 511) {
ret = -EINVAL;
goto exit;
......@@ -260,13 +268,17 @@ int vmfunc_klcd_test_wrapper(struct fipc_message *msg, unsigned int ept, vmfunc_
if (!init_pgd)
init_pgd = kallsyms_lookup_name("init_level4_pgt");
local_irq_save(flags);
if (current->nested_count++ == 0)
pick_stack(ept);
local_irq_restore(flags);
ret = vmfunc_test_wrapper(msg, test);
local_irq_save(flags);
if (--current->nested_count == 0)
drop_stack(ept);
local_irq_restore(flags);
exit:
return ret;
......@@ -367,7 +379,9 @@ vmfunc_test_wrapper(struct fipc_message *request, vmfunc_test_t test)
switch (test) {
case VMFUNC_TEST_EMPTY_SWITCH:
printk("%s: Invoking EMPTY_SWITCH test\n", __func__);
#ifdef CONFIG_DEFEAT_LAZY_TLB
remap_cr3();
#endif
vmfunc_call_empty_switch();
#ifdef CONFIG_DO_BF_PAGE_WALK
bfcall_guest_page_walk(vmfunc_load_addr, __pa(current->active_mm->pgd), 1);
......@@ -381,9 +395,6 @@ vmfunc_test_wrapper(struct fipc_message *request, vmfunc_test_t test)
int i = 0;
u64 start = rdtsc(), end;
for (; i < NUM_ITERATIONS; i++) {
#ifdef CONFIG_DEFEAT_LAZY_TLB
remap_cr3();
#endif
vmfunc_call_empty_switch();
}
end = rdtsc();
......@@ -399,6 +410,20 @@ vmfunc_test_wrapper(struct fipc_message *request, vmfunc_test_t test)
__func__, request->vmfunc_id);
vmfunc_trampoline_entry(request);
break;
case VMFUNC_TEST_RPC_CALL_BENCHMARK:
request->vmfunc_id = VMFUNC_RPC_CALL;
{
int i = 0;
u64 start = rdtsc(), end;
for (; i < NUM_ITERATIONS; i++) {
vmfunc_trampoline_entry(request);
}
end = rdtsc();
printk("%d iterations of rpc_call took %llu cycles (avg: %llu cycles)\n",
NUM_ITERATIONS, end - start, (end - start) / NUM_ITERATIONS);
}
break;
case VMFUNC_TEST_RPC_CALL:
request->vmfunc_id = VMFUNC_RPC_CALL;
vmfunc_trampoline_entry(request);
......
......@@ -31,6 +31,15 @@ null_invocation(struct fipc_message *msg)
return 0;
}
int val;
unsigned long noinline
marshal_one(struct fipc_message *msg)
{
val = fipc_get_reg0(msg);
return 0;
}
#ifdef CONFIG_DUMP_IRQ_REGS
void dump_tss(struct tss_struct *tss, int cpu)
{
......@@ -125,7 +134,7 @@ foo(struct fipc_message *msg)
void *rsp_ptr;
unsigned long rsp_top;
u64 start = rdtsc(), end;
int num_iterations = 100000;
int num_iterations = 1000000;
for(i = 0; i < num_iterations; i++) {
asm volatile("mov %%rsp, %[rsp_ptr]"
......@@ -209,6 +218,9 @@ int handle_rpc_calls(struct fipc_message *msg)
case NULL_INVOCATION:
null_invocation(msg);
break;
case MARSHAL_ONE:
marshal_one(msg);
break;
case FOO:
foo(msg);
break;
......
......@@ -68,6 +68,15 @@ void run_vmfunc_tests(void)
printk("%s: VMFUNC_TEST_RPC_CALL: Passed!\n\tValue from other domain %lx\n",
__func__, fipc_get_reg1(&msg));
/* test3a: RPC call microbenchmark */
memset(&msg, 0x0, sizeof(msg));
msg.rpc_id = MARSHAL_ONE;
fipc_set_reg0(&msg, (u64) 0xabcd);
vmfunc_klcd_test_wrapper(&msg, OTHER_DOMAIN, VMFUNC_TEST_RPC_CALL_BENCHMARK);
/* test4: RPC call and get a call back */
//for_each_online_cpu(cpu) {
cpu = smp_processor_id();
{
......
......@@ -16,6 +16,7 @@ enum fn_type {
CALLEE,
FOO,
BAR,
MARSHAL_ONE,
};
int callee(struct fipc_message *);
#define TRANSACTIONS 1000000
......