-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These are minimal bindings to Xen, for x86_64 only. The purpose of these bindings is primarily to serve as a replacement for Mini-OS in the MirageOS Xen platform stack. As such, no network or block device support is implemeted and the related Solo5 APIs are stubbed out. Only the Xen PVH v2 ABI is supported. This is available from Xen 4.10 onwards. Being based off the existing virtio bindings, page table setup is entirely static, but is extended to a 4GB identity map in order to be able to access Xen PV device rings which the hypervisor places at the top of memory below the 4GB mark. Like virtio, all pages are marked RWX for now. This will be addressed in later changes. In order for MirageOS to be able to interface directly with Xen while still using Solo5 for early boot, a number of private ABIs are introduced: 1. The location of the hypercall page is exported using the solo5__xen_HYPERCALL_PAGE symbol. 2. The location of the shared_info page is exported using the solo5__xen_HYPERVISOR_SHARED_INFO symbol. 3. The event channel upcall from Xen may be overriden by providing a strong symbol for solo5__xen_evtchn_vector_handler. These private ABIs are exclusively for the use of MirageOS, and may change or go away entirely at any time.
- Loading branch information
Showing
31 changed files
with
4,693 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright (c) 2015-2020 Contributors as noted in the AUTHORS file | ||
* | ||
* This file is part of Solo5, a sandboxed execution environment. | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software | ||
* for any purpose with or without fee is hereby granted, provided | ||
* that the above copyright notice and this permission notice appear | ||
* in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL | ||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE | ||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR | ||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
/* | ||
* bindings.h: Solo5 bindings, Xen implementation additions. | ||
* | ||
* This header file includes (supersedes) the common bindings.h for the Xen | ||
* implementation. | ||
*/ | ||
|
||
#ifndef __XEN_BINDINGS_H__ | ||
#define __XEN_BINDINGS_H__ | ||
|
||
#include "../bindings.h" | ||
#include "elf_abi.h" | ||
|
||
#include "xen/xen.h" | ||
#include "xen/event_channel.h" | ||
|
||
/* console.c: Xen console */ | ||
void console_init(void); | ||
void console_write(const char *, size_t); | ||
|
||
/* pvclock.c: Xen paravirtualized clock */ | ||
int pvclock_init(void); | ||
uint64_t pvclock_monotonic(void); | ||
uint64_t pvclock_epochoffset(void); | ||
|
||
/* time.c: Timekeeping */ | ||
void time_init(void); | ||
|
||
/* evtchn.c: Xen event channel interface */ | ||
typedef void(*evtchn_handler_fn_t)(evtchn_port_t, void *); | ||
|
||
void evtchn_init(void); | ||
void evtchn_register_handler(evtchn_port_t, evtchn_handler_fn_t, void *); | ||
evtchn_port_t evtchn_bind_virq(uint32_t); | ||
void evtchn_mask(evtchn_port_t); | ||
void evtchn_unmask(evtchn_port_t); | ||
|
||
/* Accessors for Xen shared_info and VCPU 0 info structures shared with | ||
* hypervisor. | ||
*/ | ||
extern uint8_t HYPERVISOR_SHARED_INFO[]; | ||
|
||
inline struct shared_info *SHARED_INFO(void) | ||
{ | ||
return (struct shared_info *)&HYPERVISOR_SHARED_INFO; | ||
} | ||
|
||
inline struct vcpu_info *VCPU0_INFO(void) | ||
{ | ||
return &(SHARED_INFO()->vcpu_info[0]); | ||
} | ||
|
||
#endif /* __XEN_BINDINGS_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
/* | ||
* Copyright (c) 2015-2020 Contributors as noted in the AUTHORS file | ||
* | ||
* This file is part of Solo5, a sandboxed execution environment. | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software | ||
* for any purpose with or without fee is hereby granted, provided | ||
* that the above copyright notice and this permission notice appear | ||
* in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL | ||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE | ||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR | ||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
#include "../cpu_x86_64.h" | ||
#include "xen/elfnote.h" | ||
|
||
#define ENTRY(x) .text; .globl x; .type x,%function; x: | ||
#define END(x) .size x, . - x | ||
|
||
/* | ||
* Tell Xen that we are a PVH-capable kernel. | ||
* See https://xenbits.xen.org/docs/unstable/misc/pvh.html. | ||
*/ | ||
.section .note.solo5.xen, "a", @note | ||
|
||
.align 4 | ||
.long 4 | ||
.long 4 | ||
.long XEN_ELFNOTE_PHYS32_ENTRY | ||
.ascii "Xen\0" | ||
.long _start32 | ||
|
||
.code32 | ||
|
||
/* | ||
* Xen PVH entry point. | ||
* | ||
* Xen puts us only in 32bit flat protected mode, and passes a pointer to | ||
* struct hvm_start_info in %ebx. It's our responsibility to install a page | ||
* table and switch to long mode. Notably, we can't call C code until we've | ||
* switched to long mode. | ||
*/ | ||
ENTRY(_start32) | ||
cld | ||
movl $bootstack, %esp | ||
|
||
/* Save Xen hvm_start_info pointer at top of stack, we pop it in 64bit */ | ||
pushl $0 | ||
pushl %ebx | ||
|
||
/* | ||
* Load bootstrap GDT and reload segment registers, with the exception of | ||
* CS, which will be reloaded on jumping to _start64 | ||
*/ | ||
lgdt (gdt64_ptr) | ||
|
||
movl $0x10, %eax | ||
movl %eax, %ds | ||
movl %eax, %es | ||
movl %eax, %ss | ||
|
||
xorl %eax, %eax | ||
movl %eax, %fs | ||
movl %eax, %gs | ||
|
||
/* | ||
* x86_64 switch to long mode | ||
*/ | ||
|
||
/* 1: Enable PAE */ | ||
movl %cr4, %eax | ||
orl $X86_CR4_PAE, %eax | ||
movl %eax, %cr4 | ||
|
||
/* 2: Load PML4 pointer */ | ||
movl $cpu_pml4, %eax | ||
movl %eax, %cr3 | ||
|
||
/* 3: Request long mode enable */ | ||
movl $0xc0000080, %ecx | ||
rdmsr | ||
orl $X86_EFER_LME, %eax | ||
wrmsr | ||
|
||
/* 4a: Enable paging */ | ||
movl %cr0, %eax | ||
orl $X86_CR0_PG, %eax | ||
|
||
/* 4b: CPU sets long mode enabled after this instruction */ | ||
movl %eax, %cr0 | ||
|
||
/* 5: Reload CS with a 64-bit selector */ | ||
pushw $0x08 | ||
pushl $_start64 | ||
lret | ||
|
||
/* NOTREACHED */ | ||
jmp haltme | ||
|
||
haltme: | ||
cli | ||
hlt | ||
jmp haltme | ||
END(_start32) | ||
|
||
.code64 | ||
|
||
ENTRY(_start64) | ||
movq $bootstack, %rsp | ||
xorq %rbp, %rbp | ||
|
||
/* Enable FPU and SSE units */ | ||
movq %cr0, %rax | ||
andq $(~X86_CR0_EM), %rax | ||
orq $(X86_CR0_MP | X86_CR0_NE), %rax | ||
movq %rax, %cr0 | ||
movq %cr4, %rax | ||
orq $(X86_CR4_OSXMMEXCPT | X86_CR4_OSFXSR), %rax | ||
movq %rax, %cr4 | ||
ldmxcsr (mxcsr_ptr) | ||
|
||
/* Read Xen hvm_start_info pointer */ | ||
movq -8(%rsp), %rdi | ||
|
||
/* Call into C with correct start-of-day stack alignment */ | ||
pushq $0x0 | ||
pushq $0x0 | ||
call _start | ||
|
||
/* NOTREACHED */ | ||
jmp haltme | ||
END(_start64) | ||
|
||
/* | ||
* void _newstack(uint64_t stack_start, void (*tramp)(void *), void *arg); | ||
* | ||
* Switch to a new stack at (stack_start), and transfer control to | ||
* (*tramp)(arg). | ||
*/ | ||
ENTRY(_newstack) | ||
movq %rdi, %rsp | ||
movq %rdx, %rdi | ||
|
||
/* As above, ensure correct start-of-day stack alignment */ | ||
pushq $0x0 | ||
pushq $0x0 | ||
call *%rsi | ||
|
||
/* NOTREACHED */ | ||
jmp haltme | ||
END(_newstack) | ||
|
||
.data | ||
|
||
/* | ||
* amd64 programmer's manual: | ||
* | ||
* "In long mode, segmentation is not used ... except for a few exceptions." | ||
* | ||
* Uuuyea, exceptions. | ||
* | ||
* The GDT here is used only during bootstrapping, and is reloaded by | ||
* cpu_init(). | ||
*/ | ||
|
||
.align 64 | ||
gdt64: | ||
.quad 0x0 /* 0: NULL selector */ | ||
.quad GDT_DESC_CODE_VAL /* 0x8: 64-bit code */ | ||
.quad GDT_DESC_DATA_VAL /* 0x10: 64-bit data */ | ||
gdt64_end: | ||
.align 64 | ||
|
||
.type gdt64_ptr, @object | ||
gdt64_ptr: | ||
.word gdt64_end-gdt64-1 | ||
.quad gdt64 | ||
|
||
.type mxcsr_ptr, @object | ||
mxcsr_ptr: | ||
.word 0x1f80 /* Intel SDM power-on default */ | ||
|
||
#include "pagetable.S" | ||
|
||
.section .bss | ||
|
||
/* | ||
* Stack used during bootstrapping, reloaded before calling _start2(). | ||
*/ | ||
.space 4096 | ||
bootstack: |
Oops, something went wrong.