1. 25 Oct, 2016 40 commits
    • Charlie Jacobsen's avatar
      Basic lcd module create, run, and destroy. · e0193fa4
      Charlie Jacobsen authored
      This code is ugly, but it's working.
      Tested with basic module, and appears to be working
      properly. I will soon incorporate the patched
      modprobe into the kernel tree, and then this code
      will be usable by everyone.
      The ipc code is still unimplemented. The only
      hypercall handled is yield. Also note that other
      exit conditions (e.g. external interrupt) have not
      been fully tested.
      -- kernel code calls lcd_create_as_module with
         the module's name
      -- lcd_create_as_module loads the module using
         request_lcd_module (request_lcd_module calls
         the patched modprobe to load the module, and
         the patched modprobe calls back into the lcd
         driver via the ioctrl interface to load the
      -- lcd_create_as_module then finds the loaded
         module, spawns a kernel thread and passes off
         the module to it
      -- the kernel thread initializes the lcd and
         maps the module inside it, then suspends itself
      -- lcd_run_as_module wakes up the kernel thread
         and tells it to run
      -- lcd_delete_as_module stops the kernel thread
         and deletes the module from the host kernel
      File-by-file details:
      -- lcd was not running in 64-bit mode, and my
         checks had one subtle bug
      -- fixed %cr3 load to properly load vmcs first
      -- fixed set program counter to use guest virtual
         rather than guest physical address
      -- added struct lcd to task_struct
      -- lcd pointer set to null when task_struct is
      -- made init_module and delete_module system calls
         callable from kernel code
      -- available in module.h via do_sys_init_module and
      -- simply moved the majority of the guts of the
         system calls into a non-system call, exported
      -- take an extra flag, for_lcd; when set, the init
         code skips over running (and deallocating) the
         module's init code, and the delete code skips
         over running the module exit
      -- system calls from user code set for_lcd = 0; this
         ensures existing code still works
      -- changed __request_module to __do_request_module; takes
         one extra argument, for_lcd
      -- __request_module   ==>  __do_request_module with for_lcd = 0
      -- request_lcd_module ==>  __do_request_module with for_lcd = 1
      -- call_modprobe conditionally uses lcd_modprobe_path, the path
         to a patched modprobe accessible via sysfs
      -- added lcd status enum; see source code doc
      -- three routines for creating/running/destroying
         lcd's that use modules; see source code doc
      -- added interface defns for patched modprobe to call into
         lcd driver for module init; lcd driver loads
         module (via slightly refactored module.c code) on behalf
         of modprobe
      -- implementation of routines for modules inside lcd's
      -- implementation of module init / delete for lcd's
         (uses patched module.c code)
      -- added test module for lcd module code
      -- test runs automatically when lcd module is inserted
    • Charles Jacobsen's avatar
      Simple blob successfully runs and returns in vmx. · c4fc774c
      Charles Jacobsen authored
      In the process of debugging, major corrections and
      debug checks implemented (this is a big squash):
      -- coded up entry checks documented in Intel SDM
         V3 chp 26 (this should help later if settings
         are changed, make it less risky to experiment
         and give more confidence)
      -- fixed host tr base addr bug (the worst bug! caused
         system to hang and then crash, since the tss
         was erroneous...)
      -- fixed vmx_entry to properly set host rsp before
      -- setting host sysenter and idt info
      -- fixed cs ar bytes bug
      -- fixed gdt limit bug
      -- fixed tr type bug
      -- extra settings added to cr0 and cr4, but may
         not be needed ... (debug fix attempt)
      -- lstar mstar autoload, may not be needed ...
         (debug fix attempt)
    • Charles Jacobsen's avatar
      Fixed build errors, all tests passing. · 78569fe2
      Charles Jacobsen authored
      Fixed (another) nasty casting bug in the
      code that initializes the ept pointer. I
      was using the old way of casting, and overlooking
      that I was storing a host virtual pointer
      inside a host physical pointer. This caused
      invept to fail (invept checks if the eptp is
      I also fixed invept and invvpid to print an
      error message (like vmload and vmclear), rather
      than generate an invalid opcode exception. It's
      easier to debug and understand the problem.
      In the future, we could more carefully parse the
      error returned.
    • Charles Jacobsen's avatar
    • Charlie Jacobsen's avatar
    • Charlie Jacobsen's avatar
      Introducing types for each gpa, gva, hva, hpa. · 82aa94ed
      Charlie Jacobsen authored
      Constructors and casting inlines are in arch-dep
      code header.
    • Charlie Jacobsen's avatar
      Shifted gpa map / unmap range to arch-dep code. · f9b52a46
      Charlie Jacobsen authored
      Updated tests.
    • Charles Jacobsen's avatar
      All lcd tests through 5 are passing. · a81d9641
      Charles Jacobsen authored
      Added pgd_pfn to asm/pgtables.h.
    • Charles Jacobsen's avatar
    • Charlie Jacobsen's avatar
      Removed utcb from arch-indep lcd. · c73ae4d4
      Charlie Jacobsen authored
      Changed to use macro accessor in lcd_arch. I think
      this is less confusing and less bug prone. So,
      to access lcd's utcb, do:
      struct lcd_utcb *utcb;
      utcb = LCD_ARCH_GET_UTCB(vcpu);
    • Charlie Jacobsen's avatar
      Simple explicit tss, gdt, and stack tear down. · fa05c7bf
      Charlie Jacobsen authored
      (Code before relied on free ept to free memory. But
      this could be confusing and hard to debug in the future...)
    • Charlie Jacobsen's avatar
      Simple unmapping code for ept in arch-dep code. · a6130165
      Charlie Jacobsen authored
      Just clears the ept entry.
    • Charlie Jacobsen's avatar
      More work on blob initialization. · 33d999d6
      Charlie Jacobsen authored
      -- Fixed program counter and stack pointer initialization
      -- Added guest virtual paging pointer modifier routine
      -- Added the minimum amount of data for guest virtual paging
      -- Added general routines for lcd create / destroy.
      -- Moved mm code to this file (to avoid future name clashes and
         be more self contained ... is this why kernel source files are
         so big?)
      -- Added general routine for initializing an lcd's gva.
      -- Re-factored blob initialization to use mm routines. Documented
         memory layout in the source code.
      Problem: I'm relying heavily on the ept tear down to free any
      memory mapped in there. But this is getting ugly ... Next step:
      Write quick routines to properly unmap and explicitly free memory.
    • Charlie Jacobsen's avatar
      Driver code and interface for loading a blob in an lcd (untested). · f0735fd0
      Charlie Jacobsen authored
      User code calls ioctl with LCD_RUN_BLOB ioctl number and
      lcd_blob_info (containing userspace address of blob and
      blob order) -- defined in public include/linux/lcd-domains.h.
      The blob must be N pages, and N must be a power of 2 (for
      easy driver code). blob_order = log2(N). The blob consists
      of machine instructions that are loaded in the lcd and
      executed. The machine instructions cannot access any memory,
      including the stack (for now, until gv paging is in place).
      -- Added lcd_arch_set_pc for setting the lcd's program counter.
      -- Added driver code in lcd-domains.c for handling the ioctl
         request, loading the blob from user space into a fresh lcd,
         and running the lcd (in a loop).
    • Charles Jacobsen's avatar
      Fixed tss/stack remap bug, and double free in create. · e0ca0ea1
      Charles Jacobsen authored
      Some data structures in struct lcd_arch are mapped in
      the ept (so that the lcd has access to them). When the
      ept is freed, these data structures are freed.
      All tests passing now for lcd_arch_create.
    • Charlie Jacobsen's avatar
      Starting simple regression test code, to save debugging time. · a64b8301
      Charlie Jacobsen authored
      Successful build and insmod on emulab, but errors when trying
      to create lcd (perhaps errors mapping in ept). Regression tests
      should help and save debugging time in future.
    • Charles Jacobsen's avatar
    • Charlie Jacobsen's avatar
      UTCB struct added, syscall codes, updated arch-dep code (untested). · c351910d
      Charlie Jacobsen authored
      (forgot to git add utcb header)
      Syscall (hypercall?) codes are in include/lcd-domains/syscall.h.
      Added syscall code accessor macro to lcd-domains-arch.h.
      Fixed capability register accessor macros to use %rbx.
    • Charlie Jacobsen's avatar
      UTCB struct, collapsed IPC registers into utcb (untested). · b8e5e2e4
      Charlie Jacobsen authored
      Simple name changes and slightly different access pattern
      for ipc registers. Updated headers and code. Removed ipc.h
      header for now.
    • Charlie Jacobsen's avatar
      Accessor macros for ipc, and low-level vmcall interface (untested). · 617b1f6e
      Charlie Jacobsen authored
      For portability and speed, arch-indep code should use arch-dep macros
      (in lcd-domains-arch.h) for accessing message registers.
      For x86, lcd does ipc by populating the appropriate message registers
      and executing a vmcall. For now, we assume the only reason an lcd
      would execute a vmcall is for ipc.
    • Charlie Jacobsen's avatar
      Starting code for IPC registers and access. · e51d81aa
      Charlie Jacobsen authored
      Set up new header files, under include/lcd-domains/
      -- lcd-domains.h: main include, contains struct lcd
      -- ipc.h: struct lcd_ipc_regs, for message registers
      Updated virt/lcd/lcd-domains.c to use new headers.
      Updated arch-dep code to use new struct lcd_ipc_regs.
      struct lcd_arch contains a pointer to the allocated
      page for stack / ipc registers. struct lcd (arch-indep)
      contains a pointer to the same memory (so that the
      arch-indep code can access the ipc regs directly if
      it wishes).
      Message registers should be accessed through arch-dep
      macros (to be implemented next) for portability and
      speed (some of the message registers will be
      implemented using machine regs, so the message registers
      in struct lcd_ipc_regs are `shadows').
      Message register design based on seL4. See seL4 manual,
    • Charlie Jacobsen's avatar
      Simple stack initialization code (untested). · 93be900b
      Charlie Jacobsen authored
      Stack / ipc registers buffer initialized and mapped
      in guest physical.
    • Charlie Jacobsen's avatar
      Added GDT and TSS guest physical mapping code (untested). · 543ccab0
      Charlie Jacobsen authored
      -- simple routine combining effects of ept walk and set
      -- part of arch-dep public interface
      Added mapping code to gdt init and tss init, and some
      documentation for those routines.
      Starting code for stack initialization (should be
    • Charlie Jacobsen's avatar
      GDT initialization code in place, and desc init code (untested). · fa0097b0
      Charlie Jacobsen authored
      -- load base, limit, type, etc. into a segment descriptor
      -- loads base, limit, etc. for code, data, and tss segment
         descriptors in gdt
    • Charlie Jacobsen's avatar
      Segment and desc table regs, address space layout in place (untested). · c4780c3c
      Charlie Jacobsen authored
      Address space layout includes tss, gdt, ipc registers, and small
      stack. See lcd-domains-arch.h.
      -- a tss may be required (not sure) while running in non-root,
         even though a stack switch does not occur
      -- a gdt may also be required (even though all info is written in
         the hidden part of the segment registers); again, not sure
      4 KBs is reserved for an IDT if it is needed (not mapped or
      GDT layout given in lcd-domains-arch.h. (GDT build code to
      be implemented / copied over next.)
      LDT is not used (so no need to load access rights, etc.). It
      is marked as unusable.
      Fixed segment register limit fields. These must be 32 bits and
      are always byte granularity. The granularity field in the
      access rights bits is confusing (see Intel SDM V3
    • Charlie Jacobsen's avatar
      EPT deallocation code in place (untested). · c9cb61a2
      Charlie Jacobsen authored
      -- frees all memory associated with extended
         page tables (paging structures and mapped
         physical mem)
      -- frees all memory associated with an epte
         at a level in the hierarchy
      -- uses shallow recursion to make the code
         more readable
      Simple updates to some of the EPT macros.
    • Charlie Jacobsen's avatar
      Finished arch-dep ept code. · 8f65d678
      Charlie Jacobsen authored
      lcd_arch_epte_t type for arch abstraction.
      -- simple lookup of ept entry
      -- optionally allocate ept data structures
         along the way
      -- set the host physical address in the
         (final level) ept entry, along with
         default flags
      -- returns host physical address stored in
         an ept entry
      Remaining old code will be put in arch-indep
    • Charlie Jacobsen's avatar
      Loads / stores to cr3 now handled (untested). · 40de4ae2
      Charlie Jacobsen authored
      This is necessary for e.g. the emulab machines (loads /
      stores to cr3 are not allowed in non-root, so must be
      handled by hypervisor). Code simply copies values between
      fields in lcd data structure.
    • Charlie Jacobsen's avatar
      Simple EPT fault handling code in place (untested). · c37435a0
      Charlie Jacobsen authored
      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.
    • Charlie Jacobsen's avatar
      External interrupt code in place (untested). · 1abf5ea6
      Charlie Jacobsen authored
      -- pretty much a straight copy over of the old code,
         but with comments
      -- one big difference: interrupts are assumed to be
         enabled when this routine is called (I can't see
         how kvm is allowing the handling of external interrupts
         because it disables them when it enters vmx non-root.
         See the kvm code in x86.c:vcpu_enter_guest.)
    • Charlie Jacobsen's avatar
      Set up simple lcd run (no loop) and some handling (untested). · 070e2688
      Charlie Jacobsen authored
      -- disables kernel preemption while lcd is running
      -- simple switch on vmx exit conditions
      -- for nmi's and exceptions generated by lcd
      -- for `hardware exceptions': page faults, traps,
         machine checks
    • Charlie Jacobsen's avatar
      Simple re-naming to arch-agnostic names for arch-dep interface. · c8a88195
      Charlie Jacobsen authored
      -- Moved some vmx-specific data structures into implementation file.
      -- lcd_vmx_* => lcd_arch_*
      -- updated virt/lcd/lcd-domains.c
    • Charlie Jacobsen's avatar
    • Charlie Jacobsen's avatar
    • Charlie Jacobsen's avatar
      Added header doc to lcd-vmx.h and lcd_vmx_destroy. · 4cdb5e83
      Charlie Jacobsen authored
      lcd_destroy => lcd_vmx_destroy. Pretty much a straight
      copy over, but removed some unneeded code.
    • Charles Jacobsen's avatar
      Fixed vmcs configuration bugs (small macro bugs in vmx.h). · aad218b5
      Charles Jacobsen authored
      Debug controls macros for vm exit and vm entry were
      wrong (I wonder if the kvm guys know, it's in the stable
      linux build).
      I had to enable exiting on load / save to %cr3 for it
      to run on emulab machines.
      Tweaked vmx control debugging code, cleaned up
      logic in adjust_vmx_controls, much simpler.
    • Charles Jacobsen's avatar
      Fixed bugs in lcd_vmx_create and dependencies. Clean build. · 4d27a893
      Charles Jacobsen authored
      Conditional compilation on number of autoload msr's.
    • Charlie Jacobsen's avatar
      Finished lcd_vmx_create and its dependencies (untested). · 7607ec9a
      Charlie Jacobsen authored
      vmx_setup_vmcs ==> vmx_setup_vmcs_guest_settings and
      -- execution control (e.g., interrupt handling)
      -- ept pointer
      -- %cr0 and %cr4 access control
      -- initial %cr0, %cr4
      -- segmentation--bases, limits, selectors
      -- guest EFER (long mode enabled, no syscall/sysret)
      -- initial activity and interrupt state
      -- control and segmentation regs
      -- host EFER
      -- no saving of syscall/sysret msrs since these are
         disabled in guest
      -- no page attribute table
    • Charlie Jacobsen's avatar
      About half way done with vmcs initialization code. · acbb9533
      Charlie Jacobsen authored
      lcd_create --> lcd_vmx_create, with a lot of code
      re-factored or removed for now, to keep it simple
      (no gdt, idt, isr, paging bitmap, address space
      init, etc.).
      -- basic ept initialization
      -- vmcs loading on a cpu
         -- re-factored __vmx_setup_cpu to use built-in
            segment descriptor access functions in desc.h
         -- removed host sys_enter storage, since this
            msr is disabled right now anyway
         -- more doc to understand vmcs load process
    • Charles Jacobsen's avatar
      Successful build with lcd_vmx_init and lcd_vmx_exit. · 62e4ac37
      Charles Jacobsen authored
      Added straight copy from old code of lcd_vmx_exit.
      Shifted lcd_vmx_init and lcd_vmx_exit to
      arch/x86/include/asm/lcd-vmx.h. Ideally, if we want
      this to be arch-independent, probably want to change
      header to asm/lcd.h, and routines to lcd_arch_init
      and lcd_arch_exit, or something similar.