Commit d653b8cc authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan

stack-trace: Refactored vt-x code builds, minus stack dump.

parent 8bb30af1
......@@ -803,4 +803,13 @@ static inline bool module_sig_ok(struct module *module)
}
#endif /* CONFIG_MODULE_SIG */
//FIXME: Syscalls already defined. Remove this
int do_sys_delete_module(const char *name, unsigned int flags, int for_lcd);
int do_sys_init_module(void __user *umod, unsigned long len,
const char __user *uargs, int for_lcd);
const char *get_ksymbol(struct module *mod,
unsigned long addr,
unsigned long *size,
unsigned long *offset);
#endif /* _LINUX_MODULE_H */
......@@ -337,6 +337,7 @@ const char *kallsyms_lookup(unsigned long addr,
return module_address_lookup(addr, symbolsize, offset, modname,
namebuf);
}
EXPORT_SYMBOL(kallsyms_lookup);
int lookup_symbol_name(unsigned long addr, char *symname)
{
......
......@@ -4010,7 +4010,7 @@ static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
}
static const char *get_ksymbol(struct module *mod,
const char *get_ksymbol(struct module *mod,
unsigned long addr,
unsigned long *size,
unsigned long *offset)
......@@ -4054,6 +4054,7 @@ static const char *get_ksymbol(struct module *mod,
*offset = addr - kallsyms->symtab[best].st_value;
return symname(kallsyms, best);
}
EXPORT_SYMBOL(get_ksymbol);
/* For kallsyms to ask for address resolution. NULL means not found. Careful
* not to lock to avoid deadlock on oopses, simply disable preemption. */
......
......@@ -9,6 +9,7 @@
#ifndef ASM_X86_LCD_DOMAINS_CREATE_H
#define ASM_X86_LCD_DOMAINS_CREATE_H
#include <lcd_domains/types.h>
#include <asm/lcd_domains/types.h>
#include <linux/slab.h>
......@@ -60,4 +61,7 @@ extern struct lcd_vmcs_config lcd_global_vmcs_config;
extern unsigned long *lcd_global_msr_bitmap;
extern struct lcd_vpids lcd_vpids;
#define MAX_PAT_ENTRY 7
#define VALID_PAT_TYPE 7
#endif /* ASM_X86_LCD_DOMAINS_CREATE_H */
......@@ -9,10 +9,9 @@
#ifndef ASM_X86_LCD_DOMAINS_EPT_H
#define ASM_X86_LCD_DOMAINS_EPT_H
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/types.h>
hva_t hpa2hva(hpa_t hpa);
/**
* Lookup ept entry for guest physical address a.
*
......
......@@ -27,5 +27,6 @@
#include <asm/lcd_domains/create.h>
#include <asm/lcd_domains/init.h>
#include <asm/lcd_domains/run.h>
#include <asm/lcd_domains/vmcs.h>
#endif /* ASM_X86_LCD_DOMAINS_MICROKERNEL_H */
......@@ -77,4 +77,16 @@ static inline void lcd_arch_set_syscall_ret(struct lcd_arch *lcd, u64 val)
*/
void lcd_arch_dump_lcd(struct lcd_arch *lcd);
/* Some internal data used by run */
/*
* Declared in inline assembly in vmx_enter
*
* This is how we remember what instruction to return to after the
* LCD VM exits.
*/
extern const unsigned long vmx_return;
extern DEFINE_PER_CPU(struct lcd_arch *, local_lcd_arch);
#endif /* ASM_X86_LCD_DOMAINS_RUN_H */
......@@ -8,6 +8,7 @@
#ifndef ASM_X86_LCD_DOMAINS_TYPES_H
#define ASM_X86_LCD_DOMAINS_TYPES_H
#include <asm/vmx.h>
#include <linux/mutex.h>
#include <linux/module.h>
......@@ -131,7 +132,7 @@ struct lcd_arch {
* Stuff we need to save explicitly
*/
u64 host_rsp;
struct lcd_regs regs;
struct lcd_arch_regs regs;
int shutdown;
int ret_code;
......
......@@ -75,7 +75,7 @@ static __always_inline u64 vmcs_read64(unsigned long field)
return vmcs_readl(field);
}
static void vmcs_writel(unsigned long field, unsigned long value)
static inline void vmcs_writel(unsigned long field, unsigned long value)
{
u8 error;
......@@ -88,17 +88,17 @@ static void vmcs_writel(unsigned long field, unsigned long value)
}
}
static void vmcs_write16(unsigned long field, u16 value)
static inline void vmcs_write16(unsigned long field, u16 value)
{
vmcs_writel(field, value);
}
static void vmcs_write32(unsigned long field, u32 value)
static inline void vmcs_write32(unsigned long field, u32 value)
{
vmcs_writel(field, value);
}
static void vmcs_write64(unsigned long field, u64 value)
static inline void vmcs_write64(unsigned long field, u64 value)
{
vmcs_writel(field, value);
}
......@@ -113,6 +113,6 @@ void vmx_get_cpu(struct lcd_arch *lcd_arch);
*
* Enables preemption.
*/
static void vmx_put_cpu(struct lcd_arch *lcd_arch);
void vmx_put_cpu(struct lcd_arch *lcd_arch);
#endif /* ASM_X86_LCD_DOMAINS_VMCS_H */
......@@ -11,11 +11,13 @@
*/
#include <linux/kernel.h>
#include <asm/vmx.h>
#include <lcd_domains/types.h>
#include <asm/lcd_domains/types.h>
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/vmcs.h>
#include <asm/vmx.h>
#include <asm/lcd_domains/microkernel.h>
static inline u16 vmx_get16(struct lcd_arch *t, u64 field)
{
......@@ -316,12 +318,12 @@ static int vmx_check_exec_ctrls(struct lcd_arch *t)
if (vmx_has_sec_exec(t) &&
vmx_sec_exec_has(t, SECONDARY_EXEC_ENABLE_EPT)) {
act64 = vmx_getl(t, EPT_POINTER);
if (!(vmx_capability.ept & VMX_EPTP_UC_BIT) &&
if (!(lcd_vmx_capability.ept & VMX_EPTP_UC_BIT) &&
(((act64 & ((1UL << VMX_EPT_MT_EPTE_SHIFT) - 1)) == 0))) {
LCD_ERR("ept uncacheable not supported");
return -1;
}
if (!(vmx_capability.ept & VMX_EPTP_WB_BIT) &&
if (!(lcd_vmx_capability.ept & VMX_EPTP_WB_BIT) &&
(((act64 & ((1UL << VMX_EPT_MT_EPTE_SHIFT) - 1)) == 6))) {
LCD_ERR("ept write-back not supported");
return -1;
......@@ -331,7 +333,7 @@ static int vmx_check_exec_ctrls(struct lcd_arch *t)
return -1;
}
if ((act64 & VMX_EPT_AD_ENABLE_BIT) &
!(vmx_capability.ept & VMX_EPT_AD_BIT)) {
!(lcd_vmx_capability.ept & VMX_EPT_AD_BIT)) {
LCD_ERR("ept access/dirty bit not supported");
return -1;
}
......
......@@ -8,7 +8,13 @@
*/
#include <asm/vmx.h>
#include <asm/lcd_domains/create.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <asm/desc.h>
#include <asm/lcd_domains/microkernel.h>
#include <lcd_domains/microkernel.h>
#include <asm/liblcd/address_spaces.h>
/* These are initialized by init.c */
struct kmem_cache *lcd_arch_cache;
......@@ -284,7 +290,7 @@ static void vmx_setup_vmcs_msr(struct lcd_arch *lcd_arch)
*
* Intel SDM V3 24.6.9, 31.10.1
*/
vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
vmcs_write64(MSR_BITMAP, __pa(lcd_global_msr_bitmap));
/*
* MSR Load / Store areas
......@@ -320,6 +326,38 @@ static void vmx_setup_vmcs_msr(struct lcd_arch *lcd_arch)
}
}
enum vmx_pat_type {
PAT_UC = 0, /* uncached */
PAT_WC = 1, /* Write combining */
PAT_WT = 4, /* Write Through */
PAT_WP = 5, /* Write Protected */
PAT_WB = 6, /* Write Back (default) */
PAT_UC_MINUS = 7, /* UC, but can be overriden by MTRR */
};
/**
* Sets up a corresponding PAT entry
*/
static int vmx_setup_pat_msr(unsigned char pat_entry, unsigned char pat_type)
{
u64 pat = 0;
if (pat_entry > MAX_PAT_ENTRY) {
LCD_ERR("Invalid PAT entry, cannot setup PAT MSR \n");
return -EINVAL;
}
if(pat_type > VALID_PAT_TYPE) {
LCD_ERR("Not a valid PAT type, cannot setup PAT MSR \n");
return -EINVAL;
}
pat = vmcs_readl(GUEST_IA32_PAT);
pat |= (pat_type << (pat_entry * 8));
vmcs_writel(GUEST_IA32_PAT, pat);
return 0;
}
/**
* Sets up initial guest register values in VMCS.
*
......@@ -592,16 +630,18 @@ static void vmx_setup_vmcs_guest_settings(struct lcd_arch *lcd_arch)
* Execution controls
*/
vmcs_write32(PIN_BASED_VM_EXEC_CONTROL,
vmcs_config.pin_based_exec_controls);
lcd_global_vmcs_config.pin_based_exec_controls);
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
vmcs_config.primary_proc_based_exec_controls);
lcd_global_vmcs_config.primary_proc_based_exec_controls);
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
vmcs_config.secondary_proc_based_exec_controls);
lcd_global_vmcs_config.secondary_proc_based_exec_controls);
/*
* Entry / Exit controls
*/
vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_controls);
vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_controls);
vmcs_write32(VM_ENTRY_CONTROLS,
lcd_global_vmcs_config.vmentry_controls);
vmcs_write32(VM_EXIT_CONTROLS,
lcd_global_vmcs_config.vmexit_controls);
/*
* EPT
*
......@@ -758,8 +798,8 @@ void vmx_get_cpu(struct lcd_arch *lcd_arch)
/*
* Invalidate any vpid or ept cache lines
*/
invvpid_single_context(lcd_arch->vpid);
invept_single_context(lcd_arch->ept.vmcs_ptr);
lcd_arch_ept_invvpid(lcd_arch->vpid);
lcd_arch_ept_invept(lcd_arch->ept.vmcs_ptr);
/*
* lcd_arch is not in launched state
......@@ -802,13 +842,13 @@ static int vmx_allocate_vpid(struct lcd_arch *lcd_arch)
lcd_arch->vpid = 0;
spin_lock(&vpids.lock);
vpid = find_first_zero_bit(vpids.bitmap, VMX_NR_VPIDS);
spin_lock(&lcd_vpids.lock);
vpid = find_first_zero_bit(lcd_vpids.bitmap, VMX_NR_VPIDS);
if (vpid < VMX_NR_VPIDS) {
lcd_arch->vpid = vpid;
__set_bit(vpid, vpids.bitmap);
__set_bit(vpid, lcd_vpids.bitmap);
}
spin_unlock(&vpids.lock);
spin_unlock(&lcd_vpids.lock);
return vpid >= VMX_NR_VPIDS;
}
......@@ -818,10 +858,10 @@ static int vmx_allocate_vpid(struct lcd_arch *lcd_arch)
*/
static void vmx_free_vpid(struct lcd_arch *lcd_arch)
{
spin_lock(&vpids.lock);
spin_lock(&lcd_vpids.lock);
if (lcd_arch->vpid != 0)
__clear_bit(lcd_arch->vpid, vpids.bitmap);
spin_unlock(&vpids.lock);
__clear_bit(lcd_arch->vpid, lcd_vpids.bitmap);
spin_unlock(&lcd_vpids.lock);
}
int lcd_arch_create(struct lcd_arch **out)
......
......@@ -6,35 +6,36 @@
* Copyright: University of Utah
*/
#include <linux/mm.h>
#include <lcd_domains/types.h>
#include <asm/lcd_domains/types.h>
#include <asm/lcd_domains/ept.h>
#include <asm/lcd_domains/microkernel.h>
/* INVEPT / INVVPID --------------------------------------------------*/
static inline bool cpu_has_vmx_invvpid_single(void)
{
return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
return lcd_vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
}
static inline bool cpu_has_vmx_invvpid_global(void)
{
return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
return lcd_vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
}
static inline bool cpu_has_vmx_invept_context(void)
{
return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
return lcd_vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
}
static inline bool cpu_has_vmx_invept_global(void)
{
return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
return lcd_vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
}
static inline bool cpu_has_vmx_ept_ad_bits(void)
{
return vmx_capability.ept & VMX_EPT_AD_BIT;
return lcd_vmx_capability.ept & VMX_EPT_AD_BIT;
}
static inline void __invept(int ext, u64 eptp)
......@@ -183,14 +184,6 @@ enum vmx_epte_mts {
VMX_EPTE_MT_WB = 6, /* write back */
};
enum vmx_pat_type {
PAT_UC = 0, /* uncached */
PAT_WC = 1, /* Write combining */
PAT_WT = 4, /* Write Through */
PAT_WP = 5, /* Write Protected */
PAT_WB = 6, /* Write Back (default) */
PAT_UC_MINUS = 7, /* UC, but can be overriden by MTRR */
};
/**
* Sets address in epte along with default access settings. Since
* we are using a page walk length of 4, epte's at all levels have
......@@ -578,5 +571,5 @@ static void debug_ept_lvl(lcd_arch_epte_t *dir, int lvl, int idx)
void lcd_arch_ept_dump(struct lcd_arch *lcd)
{
debug_ept_lvl(t->ept.root, 0, 0);
debug_ept_lvl(lcd->ept.root, 0, 0);
}
......@@ -7,10 +7,15 @@
* Copyright: University of Utah
*/
#include <linux/tboot.h>
#include <asm/vmx.h>
#include <asm/virtext.h>
#include <lcd_domains/types.h>
#include <asm/lcd_domains/types.h>
#include <asm/lcd_domains/microkernel.h>
#include <lcd_domains/microkernel.h>
struct lcd_vmx_capability lcd_vmx_capability;
static atomic_t vmx_enable_failed;
static DEFINE_PER_CPU(int, vmx_enabled);
......@@ -111,7 +116,7 @@ static void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr)
/**
* Checks and sets basic vmcs settings (vmxon region size, etc.)
*/
static int vmcs_config_basic_settings(struct lcd_vmx_vmcs_config *vmcs_conf)
static int vmcs_config_basic_settings(struct lcd_vmcs_config *vmcs_conf)
{
u32 msr_low;
u32 msr_high;
......@@ -144,7 +149,7 @@ static int vmcs_config_basic_settings(struct lcd_vmx_vmcs_config *vmcs_conf)
return -EIO;
vmcs_conf->size = msr_high & 0x1fff;
vmcs_conf->order = get_order(vmcs_config.size);
vmcs_conf->order = get_order(lcd_global_vmcs_config.size);
vmcs_conf->revision_id = msr_low;
return 0;
}
......@@ -203,37 +208,12 @@ static int adjust_vmx_controls(u32 *controls, u32 reserved_mask, u32 msr)
return 0;
}
#define MAX_PAT_ENTRY 7
#define VALID_PAT_TYPE 7
/**
* Sets up a corresponding PAT entry
*/
static int vmx_setup_pat_msr(unsigned char pat_entry, unsigned char pat_type)
{
u64 pat = 0;
if (pat_entry > MAX_PAT_ENTRY) {
LCD_ERR("Invalid PAT entry, cannot setup PAT MSR \n");
return -EINVAL;
}
if(pat_type > VALID_PAT_TYPE) {
LCD_ERR("Not a valid PAT type, cannot setup PAT MSR \n");
return -EINVAL;
}
pat = vmcs_readl(GUEST_IA32_PAT);
pat |= (pat_type << (pat_entry * 8));
vmcs_writel(GUEST_IA32_PAT, pat);
return 0;
}
/**
* Populates default settings in vmcs_conf for
* vm entries, vm exits, vm execution (e.g., interrupt handling),
* etc. for all lcd types.
*/
static int setup_vmcs_config(struct lcd_vmx_vmcs_config *vmcs_conf)
static int setup_vmcs_config(struct lcd_vmcs_config *vmcs_conf)
{
u32 pin_based_exec_controls;
u32 primary_proc_based_exec_controls;
......@@ -338,7 +318,7 @@ static int setup_vmcs_config(struct lcd_vmx_vmcs_config *vmcs_conf)
* Remember the EPT and VPID capabilities
*/
rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
vmx_capability.ept, vmx_capability.vpid);
lcd_vmx_capability.ept, lcd_vmx_capability.vpid);
/*
......
......@@ -8,13 +8,9 @@
#include <lcd_domains/types.h>
#include <asm/lcd_domains/types.h>
#include <asm/lcd_domains/run.h>
#include <asm/lcd_domains/microkernel.h>
static DEFINE_PER_CPU(struct lcd_arch *, local_lcd_arch);
/*
* Declared in inline assembly in vmx_enter
*/
extern const unsigned long vmx_return;
DEFINE_PER_CPU(struct lcd_arch *, local_lcd_arch);
static void dump_lcd_arch(struct lcd_arch *lcd)
{
......
......@@ -610,7 +610,7 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
return 0;
#ifdef LCD_ISOLATE
#ifndef LCD_ISOLATE
fail7:
#endif
fail6:
......
......@@ -14,7 +14,7 @@
#include <linux/spinlock.h>
#include <linux/interval_tree.h>
#include <asm/lcd_domains/main.h>
#include <asm/lcd_domains/types.h>
#include <lcd_domains/types.h>
#include <liblcd/sync_ipc.h>
#include <liblcd/syscall.h>
......
......@@ -10,7 +10,7 @@
#define LIBLCD_ADDRESS_SPACES_H
#include <lcd_domains/types.h>
#include <asm/lcd_domains/address_spaces.h> /* contains layouts */
#include <asm/liblcd/address_spaces.h> /* contains layouts */
/* HELPERS -------------------------------------------------- */
......
......@@ -7,6 +7,9 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/create.h>
#include <asm/lcd_domains/ept.h>
#include <asm/lcd_domains/check.h>
/* CREATE -------------------------------------------------- */
......
......@@ -8,12 +8,13 @@
#include <lcd_domains/microkernel.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
hva_t module_addr)
{
struct cnode *cnode;
struct lcd lcd_struct;
struct lcd *lcd_struct;
int ret;
/*
* Look up LCD
......@@ -26,7 +27,7 @@ int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
/*
* If it doesn't have an lcd_arch, fail (no underlying VM)
*/
if (!lcd->lcd_arch) {
if (!lcd_struct->lcd_arch) {
LCD_ERR("no vm");
ret = -EINVAL;
goto fail2;
......@@ -34,7 +35,7 @@ int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
/*
* Store module address in lcd_arch
*/
lcd->lcd_arch->kernel_module = hva2va(module_addr);
lcd_struct->lcd_arch->kernel_module = hva2va(module_addr);
__lcd_put(caller, cnode, lcd_struct);
......@@ -71,6 +72,7 @@ int __lcd_sprint_symbol(char *buffer, hva_t hva, struct module *extra_module)
char *modname = NULL;
unsigned long offset;
unsigned long size;
unsigned long len;
/*
* This code is motivated by kernel/kallsyms.c:__sprint_symbol
*/
......@@ -95,7 +97,7 @@ int __lcd_sprint_symbol(char *buffer, hva_t hva, struct module *extra_module)
if (!sym_name)
return sprintf(buffer, "0x%lx", hva_val(hva));
if (sym_name != buffer)
strcpy(buffer, name);
strcpy(buffer, sym_name);
}
/*
* According to doc in kernel/kallsyms.c:sprint_backtrace,
......
......@@ -20,6 +20,7 @@
#include <lcd_domains/types.h>
#include <uapi/lcd_domains.h>
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LCD driver");
......@@ -84,40 +85,12 @@ static struct miscdevice lcd_dev = {
&lcd_chardev_ops,
};
/* SYSRQ debugging -------------------------------------------------- */
static void sysrq_handle_showlcds(int key)
{
printk(KERN_ERR "==========BEGIN LCD SYSRQ INFO==========\n");
printk(KERN_ERR "Is there an LCD in non-root? %s\n",
lcd_in_non_root ? "yes" : "no");
if (lcd_in_non_root) {
printk(KERN_ERR "And it's running on cpu %d\n",
lcd_on_cpu);
}
printk(KERN_ERR "==========END LCD SYSRQ INFO==========\n");
}
static struct sysrq_key_op sysrq_showlcds_op = {
.handler = sysrq_handle_showlcds,
.help_msg = "show-lcd-info(x)",
.action_msg = "Show LCD Info",
};
/* Init / Exit ---------------------------------------- */
static int __init lcd_init(void)
{
int ret;
/*
* Register sysrq handler before we do *anything*
*/
ret = register_sysrq_key('x', &sysrq_showlcds_op);
if (ret) {
LCD_ERR("failed to register sysrq key");
goto failkey;
}
/*
* Initialize each of the subsystems
*/
......@@ -188,8 +161,6 @@ fail2:
fail1:
lcd_arch_exit();
fail0:
unregister_sysrq_key('x', &sysrq_showlcds_op);
failkey:
return ret;
}
......@@ -204,7 +175,6 @@ static void __exit lcd_exit(void)
__lcd_exit_cap_types();
cap_fini();
lcd_arch_exit();
unregister_sysrq_key('x', &sysrq_showlcds_op);
LCD_MSG("lcd microkernel exited");
}
......
......@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/ept.h>
/* MEMORY OBJECT HELPERS -------------------------------------------------- */
......
......@@ -8,6 +8,8 @@
#include <linux/sched.h>
#include <linux/kthread.h>
#include <lcd_domains/microkernel.h>
#include <asm/lcd_domains/run.h>
#include <asm/lcd_domains/create.h>
/* SYSCALL HANDLERS -------------------------------------------------- */
......
......@@ -23,6 +23,7 @@ lcd_domains-y += $(addprefix microkernel/, \
mem.o \
mem_itree.o \
run.o \
ksym.o \
)
# Arch dependent code
......
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