[kernel] Let objects inherit caps from superclasses

The main point of this change is to allow "global" capabilities defined
on the base object type. The example here is the clone capability on all
objects, which governs the ability to clone a handle.

Related changes in this commit:
- Renamed `kobject` to `object` as far as the syscall interface is
  concerned. `kobject` is the cname, but j6_cap_kobject_clone feels
  clunky.
- The above change made me realize that the "object <type>" syntax for
  specifying object references was also clunky, so now it's "ref <type>"
- Having to add `.object` on everywhere to access objects in
  interface.exposes or object.super was cumbersome, so those properties
  now return object types directly, instead of ObjectRef.
- syscall_verify.cpp.cog now generates code to check capabilities on
  handles if they're specified in the definition, even when not passing
  an object to the implementation function.
This commit is contained in:
Justin C. Miller
2022-01-29 15:22:38 -08:00
parent bdae812274
commit cd037aca15
19 changed files with 101 additions and 70 deletions

View File

@@ -1,4 +1,4 @@
object channel : kobject {
object channel : object {
uid 3ea38b96aa0e54c8
capabilities [

View File

@@ -1,7 +1,7 @@
# Channels are objects that enable synchronous IPC of
# arbitrary-sized messages.
object endpoint : kobject {
object endpoint : object {
uid c5882f24a4c03b7e
capabilities [

View File

@@ -0,0 +1,4 @@
object event : object {
uid f441e03da5516b1a
}

View File

@@ -1,5 +1,4 @@
# Mailboxes are objects that enable asynchronous IPC via event notification.
# This is a second line of documentation
object mailbox {
uid 99934ad04ece1e07
@@ -11,7 +10,7 @@ object mailbox {
method bind {
param index uint
param source object kobject
param source ref object
param event uint
}

View File

@@ -1,6 +1,11 @@
# The base type of all kernel-exposed objects
object kobject [virtual] {
object object [virtual] {
uid 667f61fb2cd57bb4
cname kobject
capabilities [
clone
]
# Get the internal kernel object id of an object
method koid {
@@ -17,9 +22,9 @@ object kobject [virtual] {
# Block the current thread waiting for an one of multiple
# objects to assert one of a set of signals
method wait_many [static] {
param handles object kobject [list] # The objects to wait on
param mask uint64 # Bitmap of which signals to wait for
param handle object kobject [out] # Returns the object that signalled
param signals uint64 [out] # Returns the state of the signals
param handles ref object [list] # The objects to wait on
param mask uint64 # Bitmap of which signals to wait for
param handle ref object [out] # Returns the object that signalled
param signals uint64 [out] # Returns the state of the signals
}
}

View File

@@ -1,9 +1,9 @@
import "objects/kobject.def"
import "objects/object.def"
# Processes are a collection of handles and a virtual memory
# space inside which threads are run.
object process : kobject {
object process : object {
uid 0c69ee0b7502ba31
capabilities [
@@ -25,7 +25,7 @@ object process : kobject {
# Give the given process a handle that points to the same
# object as the specified handle.
method give_handle {
param target object kobject [handle] # A handle in the caller process to send
param received object kobject [out optional] # The handle as the recipient will see it
param target ref object [handle] # A handle in the caller process to send
param received ref object [out optional] # The handle as the recipient will see it
}
}

View File

@@ -3,7 +3,7 @@ import "objects/vma.def"
# The system object represents a handle to kernel functionality
# needed by drivers and other priviledged services
object system : kobject {
object system : object {
uid fa72506a2cf71a30
capabilities [
@@ -21,17 +21,17 @@ object system : kobject {
# Ask the kernel to send this process messages whenever
# the given IRQ fires
method bind_irq [cap:bind_irq] {
param dest object endpoint # Endpoint that will receive messages
param irq uint # IRQ number to bind
param dest ref endpoint # Endpoint that will receive messages
param irq uint # IRQ number to bind
}
# Create a VMA and map an area of physical memory into it,
# also mapping that VMA into the current process
method map_phys [cap:map_phys] {
param area object vma [out] # Receives a handle to the VMA created
param phys address # The physical address of the area
param size size # Size of the area, in pages
param flags uint32 # Flags to apply to the created VMA
param area ref vma [out] # Receives a handle to the VMA created
param phys address # The physical address of the area
param size size # Size of the area, in pages
param flags uint32 # Flags to apply to the created VMA
}
# Request the kernel change the IOPL for this process. The only values

View File

@@ -1,4 +1,4 @@
object thread : kobject {
object thread : object {
uid 11f23e593d5761bd
capabilities [
@@ -6,7 +6,7 @@ object thread : kobject {
]
method create [constructor] {
param process object process [cap:create_thread]
param process ref process [cap:create_thread]
param stack_top address
param entrypoint address
}

View File

@@ -1,6 +1,6 @@
import "objects/process.def"
object vma : kobject {
object vma : object {
uid d6a12b63b3ed3937
cname vm_area
@@ -22,12 +22,12 @@ object vma : kobject {
}
method map [cap:map] {
param process object process
param process ref process
param address address
}
method unmap [cap:unmap] {
param process object process
param process ref process
}
method resize [cap:resize] {

View File

@@ -1,4 +1,4 @@
import "objects/kobject.def"
import "objects/object.def"
import "objects/channel.def"
import "objects/endpoint.def"
@@ -11,14 +11,14 @@ import "objects/vma.def"
interface syscalls [syscall] {
uid 01d9b6a948961097
expose object system
expose object kobject
expose object event
expose object process
expose object thread
expose object channel
expose object endpoint
expose object vma
expose ref object
expose ref system
expose ref event
expose ref process
expose ref thread
expose ref channel
expose ref endpoint
expose ref vma
# Simple no-op syscall for testing
function noop
@@ -32,14 +32,14 @@ interface syscalls [syscall] {
# supplied list is not big enough, will set the size
# needed in `size` and return j6_err_insufficient
function handle_list {
param handles object kobject [list inout optional] # A list of handles to be filled
param handles ref object [list inout optional] # A list of handles to be filled
}
# Create a clone of an existing handle, possibly with
# some capabilities masked out.
function handle_clone {
param handle object kobject [handle] # The handle to clone
param clone object kobject [out] # The new handle
param mask uint32 # The capability bitmask
param orig ref object [handle cap:clone] # The handle to clone
param clone ref object [out] # The new handle
param mask uint32 # The capability bitmask
}
}