github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/ring0/defs_arm64.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build arm64
    16  // +build arm64
    17  
    18  package ring0
    19  
    20  import (
    21  	"github.com/MerlinKodo/gvisor/pkg/hostarch"
    22  )
    23  
    24  const (
    25  	// UserspaceSize is the total size of userspace.
    26  	UserspaceSize = uintptr(1) << VirtualAddressBits
    27  
    28  	// MaximumUserAddress is the largest possible user address.
    29  	MaximumUserAddress = (UserspaceSize - 1) & ^uintptr(hostarch.PageSize-1)
    30  
    31  	// KernelStartAddress is the starting kernel address.
    32  	KernelStartAddress = ^uintptr(0) - (UserspaceSize - 1)
    33  )
    34  
    35  // KernelArchState contains architecture-specific state.
    36  type KernelArchState struct {
    37  }
    38  
    39  // CPUArchState contains CPU-specific arch state.
    40  type CPUArchState struct {
    41  	// stack is the stack used for interrupts on this CPU.
    42  	stack [128]byte
    43  
    44  	// errorCode is the error code from the last exception.
    45  	errorCode uintptr
    46  
    47  	// errorType indicates the type of error code here, it is always set
    48  	// along with the errorCode value above.
    49  	//
    50  	// It will either by 1, which indicates a user error, or 0 indicating a
    51  	// kernel error. If the error code below returns false (kernel error),
    52  	// then it cannot provide relevant information about the last
    53  	// exception.
    54  	errorType uintptr
    55  
    56  	// faultAddr is the value of far_el1.
    57  	faultAddr uintptr
    58  
    59  	// el0Fp is the address of application's fpstate.
    60  	el0Fp uintptr
    61  
    62  	// ttbr0Kvm is the value of ttbr0_el1 for sentry.
    63  	ttbr0Kvm uintptr
    64  
    65  	// ttbr0App is the value of ttbr0_el1 for applicaton.
    66  	ttbr0App uintptr
    67  
    68  	// exception vector.
    69  	vecCode Vector
    70  
    71  	// application context pointer.
    72  	appAddr uintptr
    73  
    74  	// lazyVFP is the value of cpacr_el1.
    75  	lazyVFP uintptr
    76  
    77  	// appASID is the asid value of guest application.
    78  	appASID uintptr
    79  }
    80  
    81  // ErrorCode returns the last error code.
    82  //
    83  // The returned boolean indicates whether the error code corresponds to the
    84  // last user error or not. If it does not, then fault information must be
    85  // ignored. This is generally the result of a kernel fault while servicing a
    86  // user fault.
    87  //
    88  //go:nosplit
    89  func (c *CPU) ErrorCode() (value uintptr, user bool) {
    90  	return c.errorCode, c.errorType != 0
    91  }
    92  
    93  // ClearErrorCode resets the error code.
    94  //
    95  //go:nosplit
    96  func (c *CPU) ClearErrorCode() {
    97  	c.errorCode = 0 // No code.
    98  	c.errorType = 1 // User mode.
    99  }
   100  
   101  // FaultAddr returns the last fault address.
   102  //
   103  //go:nosplit
   104  func (c *CPU) FaultAddr() (value uintptr) {
   105  	return c.faultAddr
   106  }
   107  
   108  //go:nosplit
   109  func (c *CPU) SetTtbr0Kvm(value uintptr) {
   110  	c.ttbr0Kvm = value
   111  }
   112  
   113  //go:nosplit
   114  func (c *CPU) SetTtbr0App(value uintptr) {
   115  	c.ttbr0App = value
   116  }
   117  
   118  //go:nosplit
   119  func (c *CPU) GetVector() (value Vector) {
   120  	return c.vecCode
   121  }
   122  
   123  //go:nosplit
   124  func (c *CPU) SetAppAddr(value uintptr) {
   125  	c.appAddr = value
   126  }
   127  
   128  // GetLazyVFP returns the value of cpacr_el1.
   129  //
   130  //go:nosplit
   131  func (c *CPU) GetLazyVFP() (value uintptr) {
   132  	return c.lazyVFP
   133  }
   134  
   135  // SwitchArchOpts are embedded in SwitchOpts.
   136  type SwitchArchOpts struct {
   137  	// UserASID indicates that the application ASID to be used on switch,
   138  	UserASID uint16
   139  
   140  	// KernelASID indicates that the kernel ASID to be used on return,
   141  	KernelASID uint16
   142  }