ring0

package
v0.0.0-...-23e6066 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2018 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package ring0 provides basic operating system-level stubs.

Index

Constants

View Source
const (
	// KernelFlagsSet should always be set in the kernel.
	KernelFlagsSet = _RFLAGS_RESERVED

	// UserFlagsSet are always set in userspace.
	UserFlagsSet = _RFLAGS_RESERVED | _RFLAGS_IF

	// KernelFlagsClear should always be clear in the kernel.
	KernelFlagsClear = _RFLAGS_IF | _RFLAGS_NT | _RFLAGS_IOPL

	// UserFlagsClear are always cleared in userspace.
	UserFlagsClear = _RFLAGS_NT | _RFLAGS_IOPL
)
View Source
const (
	// FlagFull indicates that a full restore should be not, not a fast
	// restore (on the syscall return path.)
	FlagFull = 1 << iota

	// FlagFlush indicates that a full TLB flush is required.
	FlagFlush
)
View Source
const (
	SegmentDescriptorAccess     SegmentDescriptorFlags = 1 << 8  // Access bit (always set).
	SegmentDescriptorWrite                             = 1 << 9  // Write permission.
	SegmentDescriptorExpandDown                        = 1 << 10 // Grows down, not used.
	SegmentDescriptorExecute                           = 1 << 11 // Execute permission.
	SegmentDescriptorSystem                            = 1 << 12 // Zero => system, 1 => user code/data.
	SegmentDescriptorPresent                           = 1 << 15 // Present.
	SegmentDescriptorAVL                               = 1 << 20 // Available.
	SegmentDescriptorLong                              = 1 << 21 // Long mode.
	SegmentDescriptorDB                                = 1 << 22 // 16 or 32-bit.
	SegmentDescriptorG                                 = 1 << 23 // Granularity: page or byte.
)

SegmentDescriptorFlag declarations.

Variables

View Source
var (
	// UserspaceSize is the total size of userspace.
	UserspaceSize = uintptr(1) << (VirtualAddressBits() - 1)

	// MaximumUserAddress is the largest possible user address.
	MaximumUserAddress = (UserspaceSize - 1) & ^uintptr(usermem.PageSize-1)

	// KernelStartAddress is the starting kernel address.
	KernelStartAddress = ^uintptr(0) - (UserspaceSize - 1)
)
View Source
var LoadFloatingPoint func(*byte)

LoadFloatingPoint loads floating point state by the most efficient mechanism available (set by Init).

View Source
var SaveFloatingPoint func(*byte)

SaveFloatingPoint saves floating point state by the most efficient mechanism available (set by Init).

Functions

func Emit

func Emit(w io.Writer)

Emit prints architecture-specific offsets.

func Halt

func Halt()

Halt halts execution.

func Init

func Init(featureSet *cpuid.FeatureSet)

Init sets function pointers based on architectural features.

This must be called prior to using ring0.

func IsCanonical

func IsCanonical(addr uint64) bool

IsCanonical indicates whether addr is canonical per the amd64 spec.

func PhysicalAddressBits

func PhysicalAddressBits() uint32

PhysicalAddressBits returns the number of bits available for physical addresses.

FIXME: This should use the cpuid passed to Init.

func ReadCR2

func ReadCR2() uintptr

ReadCR2 reads the current CR2 value.

func Start

func Start()

Start is the CPU entrypoint.

The following start conditions must be satisfied:

  • AX should contain the CPU pointer.
  • c.GDT() should be loaded as the GDT.
  • c.IDT() should be loaded as the IDT.
  • c.CR0() should be the current CR0 value.
  • c.CR3() should be set to the kernel PageTables.
  • c.CR4() should be the current CR4 value.
  • c.EFER() should be the current EFER value.

The CPU state will be set to c.Registers().

func VirtualAddressBits

func VirtualAddressBits() uint32

VirtualAddressBits returns the number bits available for virtual addresses.

Note that sign-extension semantics apply to the highest order bit.

FIXME: This should use the cpuid passed to Init.

Types

type CPU

type CPU struct {

	// CPUArchState is architecture-specific state.
	CPUArchState

	// KernelException handles an exception during kernel execution.
	//
	// Return from this call will restore registers and return to the kernel: the
	// registers must be modified directly.
	//
	// If this function is not provided, a kernel exception results in halt.
	//
	// This must be go:nosplit, as this will be on the interrupt stack.
	// Closures are permitted, as the pointer to the closure frame is not
	// passed on the stack.
	KernelException func(Vector)

	// KernelSyscall is called for kernel system calls.
	//
	// Return from this call will restore registers and return to the kernel: the
	// registers must be modified directly.
	//
	// If this function is not provided, a kernel exception results in halt.
	//
	// This must be go:nosplit, as this will be on the interrupt stack.
	// Closures are permitted, as the pointer to the closure frame is not
	// passed on the stack.
	KernelSyscall func()
	// contains filtered or unexported fields
}

CPU is the per-CPU struct.

func Current

func Current() *CPU

Current returns the current CPU.

Its use is only legal in the KernelSyscall and KernelException contexts, which must all be guarded go:nosplit.

func (*CPU) CR0

func (c *CPU) CR0() uint64

CR0 returns the CPU's CR0 value.

func (*CPU) CR4

func (c *CPU) CR4() uint64

CR4 returns the CPU's CR4 value.

func (*CPU) EFER

func (c *CPU) EFER() uint64

EFER returns the CPU's EFER value.

func (*CPU) ErrorCode

func (c *CPU) ErrorCode() (value uintptr, user bool)

ErrorCode returns the last error code.

The returned boolean indicates whether the error code corresponds to the last user error or not. If it does not, then fault information must be ignored. This is generally the result of a kernel fault while servicing a user fault.

func (*CPU) GDT

func (c *CPU) GDT() (uint64, uint16)

GDT returns the CPU's GDT base and limit.

func (*CPU) IDT

func (c *CPU) IDT() (uint64, uint16)

IDT returns the CPU's IDT base and limit.

func (*CPU) Init

func (c *CPU) Init(k *Kernel)

Init allows the initialization of a CPU from a kernel without allocation. The same constraints as NewCPU apply.

Init allows embedding in other objects.

func (*CPU) Registers

func (c *CPU) Registers() *syscall.PtraceRegs

Registers returns a modifiable-copy of the kernel registers.

This is explicitly safe to call during KernelException and KernelSyscall.

func (*CPU) StackTop

func (c *CPU) StackTop() uint64

StackTop returns the kernel's stack address.

func (*CPU) SwitchToUser

func (c *CPU) SwitchToUser(regs *syscall.PtraceRegs, fpState *byte, pt *pagetables.PageTables, flags Flags) (vector Vector)

SwitchToUser performs either a sysret or an iret.

The return value is the vector that interrupted execution.

This function will not split the stack. Callers will probably want to call runtime.entersyscall (and pair with a call to runtime.exitsyscall) prior to calling this function.

When this is done, this region is quite sensitive to things like system calls. After calling entersyscall, any memory used must have been allocated and no function calls without go:nosplit are permitted. Any calls made here are protected appropriately (e.g. IsCanonical and CR3).

Also note that this function transitively depends on the compiler generating code that uses IP-relative addressing inside of absolute addresses. That's the case for amd64, but may not be the case for other architectures.

func (*CPU) TSS

func (c *CPU) TSS() (uint64, uint16, *SegmentDescriptor)

TSS returns the CPU's TSS base, limit and value.

type CPUArchState

type CPUArchState struct {
	// contains filtered or unexported fields
}

CPUArchState contains CPU-specific arch state.

type Flags

type Flags uintptr

Flags contains flags related to switch.

type Gate64

type Gate64 struct {
	// contains filtered or unexported fields
}

Gate64 is a 64-bit task, trap, or interrupt gate.

type Kernel

type Kernel struct {
	KernelArchState
}

Kernel is a global kernel object.

This contains global state, shared by multiple CPUs.

func New

func New(opts KernelOpts) *Kernel

New creates a new kernel.

N.B. that constraints on KernelOpts must be satisfied.

Init must have been called.

func (*Kernel) NewCPU

func (k *Kernel) NewCPU() *CPU

NewCPU creates a new CPU associated with this Kernel.

Note that execution of the new CPU must begin at Start, with constraints as documented. Initialization is not completed by this method alone.

See also Init.

type KernelArchState

type KernelArchState struct {
	KernelOpts
	// contains filtered or unexported fields
}

KernelArchState contains architecture-specific state.

type KernelOpts

type KernelOpts struct {
	// PageTables are the kernel pagetables; this must be provided.
	PageTables *pagetables.PageTables
}

KernelOpts has initialization options for the kernel.

type SegmentDescriptor

type SegmentDescriptor struct {
	// contains filtered or unexported fields
}

SegmentDescriptor is a segment descriptor.

var (
	UserCodeSegment32 SegmentDescriptor
	UserDataSegment   SegmentDescriptor
	UserCodeSegment64 SegmentDescriptor
	KernelCodeSegment SegmentDescriptor
	KernelDataSegment SegmentDescriptor
)

Standard segments.

func (*SegmentDescriptor) Base

func (d *SegmentDescriptor) Base() uint32

Base returns the descriptor's base linear address.

func (*SegmentDescriptor) DPL

func (d *SegmentDescriptor) DPL() int

DPL returns the descriptor privilege level.

func (*SegmentDescriptor) Flags

Flags returns descriptor flags.

func (*SegmentDescriptor) Limit

func (d *SegmentDescriptor) Limit() uint32

Limit returns the descriptor size.

type SegmentDescriptorFlags

type SegmentDescriptorFlags uint32

SegmentDescriptorFlags are typed flags within a descriptor.

type Selector

type Selector uint16

Selector is a segment Selector.

const (
	Kcode   Selector = segKcode << 3
	Kdata   Selector = segKdata << 3
	Ucode32 Selector = (segUcode32 << 3) | 3
	Udata   Selector = (segUdata << 3) | 3
	Ucode64 Selector = (segUcode64 << 3) | 3
	Tss     Selector = segTss << 3
)

Selectors.

type TaskState64

type TaskState64 struct {
	// contains filtered or unexported fields
}

TaskState64 is a 64-bit task state structure.

type Vector

type Vector uintptr

Vector is an exception vector.

const (
	DivideByZero Vector = iota
	Debug
	NMI
	Breakpoint
	Overflow
	BoundRangeExceeded
	InvalidOpcode
	DeviceNotAvailable
	DoubleFault
	CoprocessorSegmentOverrun
	InvalidTSS
	SegmentNotPresent
	StackSegmentFault
	GeneralProtectionFault
	PageFault

	X87FloatingPointException
	AlignmentCheck
	MachineCheck
	SIMDFloatingPointException
	VirtualizationException
	SecurityException = 0x1e
	SyscallInt80      = 0x80
)

Exception vectors.

const (
	Syscall Vector = _NR_INTERRUPTS
)

System call vectors.

Directories

Path Synopsis
Binary gen_offsets is a helper for generating offset headers.
Binary gen_offsets is a helper for generating offset headers.
Package pagetables provides a generic implementation of pagetables.
Package pagetables provides a generic implementation of pagetables.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL