Merge pull request #4874 from zhlhahaha:2022

PiperOrigin-RevId: 346134026
This commit is contained in:
gVisor bot 2020-12-07 11:11:17 -08:00
commit 7527371f0f
4 changed files with 21 additions and 202 deletions

View File

@ -72,7 +72,6 @@ go_library(
"lib_amd64.s",
"lib_arm64.go",
"lib_arm64.s",
"lib_arm64_unsafe.go",
"ring0.go",
],
visibility = ["//pkg/sentry:internal"],

View File

@ -132,40 +132,6 @@
MOVD offset+PTRACE_R29(reg), R29; \
MOVD offset+PTRACE_R30(reg), R30;
// NOP-s
#define nop31Instructions() \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f; \
WORD $0xd503201f;
#define ESR_ELx_EC_UNKNOWN (0x00)
#define ESR_ELx_EC_WFx (0x01)
/* Unallocated EC: 0x02 */
@ -764,79 +730,43 @@ TEXT ·El0_error_invalid(SB),NOSPLIT,$0
B ·Shutdown(SB)
// Vectors implements exception vector table.
// The start address of exception vector table should be 11-bits aligned.
// For detail, please refer to arm developer document:
// https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table
// Also can refer to the code in linux kernel: arch/arm64/kernel/entry.S
TEXT ·Vectors(SB),NOSPLIT,$0
PCALIGN $2048
B ·El1_sync_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El1_irq_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El1_fiq_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El1_error_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El1_sync(SB)
nop31Instructions()
PCALIGN $128
B ·El1_irq(SB)
nop31Instructions()
PCALIGN $128
B ·El1_fiq(SB)
nop31Instructions()
PCALIGN $128
B ·El1_error(SB)
nop31Instructions()
PCALIGN $128
B ·El0_sync(SB)
nop31Instructions()
PCALIGN $128
B ·El0_irq(SB)
nop31Instructions()
PCALIGN $128
B ·El0_fiq(SB)
nop31Instructions()
PCALIGN $128
B ·El0_error(SB)
nop31Instructions()
PCALIGN $128
B ·El0_sync_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El0_irq_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El0_fiq_invalid(SB)
nop31Instructions()
PCALIGN $128
B ·El0_error_invalid(SB)
nop31Instructions()
// The exception-vector-table is required to be 11-bits aligned.
// Please see Linux source code as reference: arch/arm64/kernel/entry.s.
// For gvisor, I defined it as 4K in length, filled the 2nd 2K part with NOPs.
// So that, I can safely move the 1st 2K part into the address with 11-bits alignment.
WORD $0xd503201f //nop
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()
WORD $0xd503201f
nop31Instructions()

View File

@ -62,6 +62,4 @@ func DisableVFP()
// Init sets function pointers based on architectural features.
//
// This must be called prior to using ring0.
func Init() {
rewriteVectors()
}
func Init() {}

View File

@ -1,108 +0,0 @@
// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build arm64
package ring0
import (
"reflect"
"syscall"
"unsafe"
"gvisor.dev/gvisor/pkg/safecopy"
"gvisor.dev/gvisor/pkg/usermem"
)
const (
nopInstruction = 0xd503201f
instSize = unsafe.Sizeof(uint32(0))
vectorsRawLen = 0x800
)
func unsafeSlice(addr uintptr, length int) (slice []uint32) {
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&slice))
hdr.Data = addr
hdr.Len = length / int(instSize)
hdr.Cap = length / int(instSize)
return slice
}
// Work around: move ring0.Vectors() into a specific address with 11-bits alignment.
//
// According to the design documentation of Arm64,
// the start address of exception vector table should be 11-bits aligned.
// Please see the code in linux kernel as reference: arch/arm64/kernel/entry.S
// But, we can't align a function's start address to a specific address by using golang.
// We have raised this question in golang community:
// https://groups.google.com/forum/m/#!topic/golang-dev/RPj90l5x86I
// This function will be removed when golang supports this feature.
//
// There are 2 jobs were implemented in this function:
// 1, move the start address of exception vector table into the specific address.
// 2, modify the offset of each instruction.
func rewriteVectors() {
vectorsBegin := reflect.ValueOf(Vectors).Pointer()
// The exception-vector-table is required to be 11-bits aligned.
// And the size is 0x800.
// Please see the documentation as reference:
// https://developer.arm.com/docs/100933/0100/aarch64-exception-vector-table
//
// But, golang does not allow to set a function's address to a specific value.
// So, for gvisor, I defined the size of exception-vector-table as 4K,
// filled the 2nd 2K part with NOP-s.
// So that, I can safely move the 1st 2K part into the address with 11-bits alignment.
//
// So, the prerequisite for this function to work correctly is:
// vectorsSafeLen >= 0x1000
// vectorsRawLen = 0x800
vectorsSafeLen := int(safecopy.FindEndAddress(vectorsBegin) - vectorsBegin)
if vectorsSafeLen < 2*vectorsRawLen {
panic("Can't update vectors")
}
vectorsSafeTable := unsafeSlice(vectorsBegin, vectorsSafeLen) // Now a []uint32
vectorsRawLen32 := vectorsRawLen / int(instSize)
offset := vectorsBegin & (1<<11 - 1)
if offset != 0 {
offset = 1<<11 - offset
}
pageBegin := (vectorsBegin + offset) & ^uintptr(usermem.PageSize-1)
_, _, errno := syscall.Syscall(syscall.SYS_MPROTECT, uintptr(pageBegin), uintptr(usermem.PageSize), uintptr(syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC))
if errno != 0 {
panic(errno.Error())
}
offset = offset / instSize // By index, not bytes.
// Move exception-vector-table into the specific address, should uses memmove here.
for i := 1; i <= vectorsRawLen32; i++ {
vectorsSafeTable[int(offset)+vectorsRawLen32-i] = vectorsSafeTable[vectorsRawLen32-i]
}
// Adjust branch since instruction was moved forward.
for i := 0; i < vectorsRawLen32; i++ {
if vectorsSafeTable[int(offset)+i] != nopInstruction {
vectorsSafeTable[int(offset)+i] -= uint32(offset)
}
}
_, _, errno = syscall.Syscall(syscall.SYS_MPROTECT, uintptr(pageBegin), uintptr(usermem.PageSize), uintptr(syscall.PROT_READ|syscall.PROT_EXEC))
if errno != 0 {
panic(errno.Error())
}
}