73774def6b
This patch adds a simple non-driver protection domain sample to serve as an example for defining other non-driver protection domains. It simply performs a ping-pong test of protection domain switching latency during boot, including optional accesses to a private metadata region, and prints out the results.
211 lines
7 KiB
Plaintext
211 lines
7 KiB
Plaintext
/*
|
|
* Copyright (C) 2015-2016, Intel Corporation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
OUTPUT_FORMAT("elf32-i386")
|
|
|
|
ENTRY(start)
|
|
|
|
SECTIONS {
|
|
/*
|
|
OS-Dev Wiki says it is common for kernels to start at 1M. Addresses before that
|
|
are used by BIOS/EFI, the bootloader and memory-mapped I/O.
|
|
|
|
The UEFI GenFw program inserts a 0x220-byte offset between the image base and
|
|
the .text section. We add that same offset here to align the symbols in the
|
|
UEFI DLL with those in the final UEFI binary to make debugging easier.
|
|
*/
|
|
. = 1M + 0x220;
|
|
|
|
.text.boot : ALIGN (32)
|
|
{
|
|
*(.multiboot)
|
|
*(.boot_text)
|
|
|
|
/*
|
|
Fill out the section to the next 4K boundary so that the UEFI GenFw
|
|
program does not shift the following .text section forward into the
|
|
gap and perturb the symbols. This only works if the size of this
|
|
section is less than 4K - 0x220 bytes.
|
|
*/
|
|
. = 4K - 0x220;
|
|
}
|
|
|
|
/*
|
|
It is actually desired that each of the following sections be page-
|
|
aligned. However, the UEFI GenFw program ratchets up its alignment
|
|
granularity to the maximum granularity discovered in its input file.
|
|
Using page-alignment perturbs the symbols, hindering debugging. Thus,
|
|
this file simply pads each section out to the desired page alignment and
|
|
declares a section alignment granularity of 32 bytes.
|
|
*/
|
|
|
|
.text : ALIGN (32)
|
|
{
|
|
*(.text*)
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
_stext_addr = ADDR(.text);
|
|
_etext_addr = ADDR(.text) + SIZEOF(.text);
|
|
|
|
.data.stack : ALIGN (32)
|
|
{
|
|
/*
|
|
Introduce a guard band page before the stacks to facilitate stack
|
|
overflow detection. This approach wastes a page of memory for each
|
|
guard band, but has the advantage of enabling an identity mapping
|
|
for all linear to physical addresses except those in the MMIO
|
|
regions. The guard bands are marked not-present in the page tables
|
|
to facilitate stack overflow detection.
|
|
|
|
This padding must be placed inside of the section, or else it will
|
|
get dropped when the UEFI GenFw program generates the UEFI binary.
|
|
*/
|
|
. += 4K;
|
|
|
|
/*
|
|
Place the main stack first so that an overflow is detected and does
|
|
not overwrite the interrupt or supervisor stacks. Usage of the
|
|
interrupt and stack is predictable, since it is only used by short
|
|
trampoline code sequences that quickly pivot to the main stack.
|
|
*/
|
|
*(.main_stack)
|
|
*(.int_stack)
|
|
*(.exc_stack)
|
|
|
|
/*
|
|
The combined sizes of the stacks is an even multiple of 4K, so there
|
|
is no need to align the location counter here.
|
|
*/
|
|
|
|
/*
|
|
Introduce a guard band page after the stacks to detect stack underflow.
|
|
Note that an underflow that only affects the interrupt and supervisor
|
|
stacks will not generate a page fault. Detecting such conditions by
|
|
placing the interrupt and supervisor stacks on separate pages would
|
|
substantially increase memory usage.
|
|
*/
|
|
. += 4K;
|
|
}
|
|
|
|
.data : ALIGN (32)
|
|
{
|
|
/*
|
|
The UEFI GenFw program treats all sections that are alloc and read-
|
|
only as code sections. By that criteria, .rodata would be a code
|
|
section, but making such data executable is undesirable. Thus, this
|
|
script lumps in .rodata with other data. It may be desirable in the
|
|
future to actually write-protect this data.
|
|
*/
|
|
*(.rodata*)
|
|
*(.data*)
|
|
|
|
_sdata_kern_startup_func = .;
|
|
KEEP(*(.kern_startup_func))
|
|
_edata_kern_startup_func = .;
|
|
|
|
/*
|
|
These could alternatively be treated as read-only data to prevent tampering
|
|
from the user privilege level.
|
|
*/
|
|
_sdata_shared_isr = .;
|
|
KEEP(*(.shared_isr_data*))
|
|
_edata_shared_isr = .;
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
.bss : ALIGN (32)
|
|
{
|
|
*(COMMON)
|
|
*(.bss*)
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
_sdata_addr = ADDR(.data);
|
|
_edata_addr = ADDR(.bss) + SIZEOF(.bss);
|
|
|
|
.bss.kern (NOLOAD) : ALIGN (32)
|
|
{
|
|
/*
|
|
Page-aligned data is output first.
|
|
It is infeasible to apply a page-alignment attribute to them in the
|
|
source code, because that increases the alignment of this section to
|
|
be page-aligned, which causes problems when generating a UEFI binary
|
|
as described above.
|
|
*/
|
|
*(.page_aligned_kern_bss)
|
|
*(.kern_bss)
|
|
|
|
syscalls_entrypoints = .;
|
|
*(.syscall_bss)
|
|
syscalls_entrypoints_end = .;
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
_ebss_syscall_addr = ADDR(.bss.kern) + SIZEOF(.bss.kern);
|
|
|
|
.bss.kern_priv (NOLOAD) : ALIGN (32)
|
|
{
|
|
prot_domains_kern_data = .;
|
|
/*
|
|
The kernel and app protection domain control structures must always
|
|
be placed in the first two slots in this order, so that they have
|
|
well-known protection domain IDs:
|
|
*/
|
|
*(.kern_prot_dom_bss)
|
|
*(.app_prot_dom_bss)
|
|
*(.prot_dom_bss)
|
|
prot_domains_kern_data_end = .;
|
|
|
|
*(.gdt_bss_start)
|
|
*(.gdt_bss_mid)
|
|
*(.gdt_bss)
|
|
_ebss_gdt_addr = .;
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
_sbss_kern_addr = ADDR(.bss.kern);
|
|
_ebss_kern_addr = ADDR(.bss.kern_priv) + SIZEOF(.bss.kern_priv);
|
|
|
|
.bss.meta (NOLOAD) : ALIGN (32)
|
|
{
|
|
*(.meta_bss)
|
|
|
|
. = ALIGN(4K);
|
|
}
|
|
|
|
_ebss_pre_dma_addr = ALIGN(32);
|
|
}
|