首页 > 其他 > 详细

gvisor bluepillHandler

时间:2021-01-14 22:17:25      阅读:23      评论:0      收藏:0      [点我收藏+]

 

 

root@cloud:~# docker exec -it test ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=42 time=56.182 ms
64 bytes from 8.8.8.8: seq=1 ttl=42 time=55.559 ms
64 bytes from 8.8.8.8: seq=2 ttl=42 time=77.515 ms
64 bytes from 8.8.8.8: seq=3 ttl=42 time=55.752 ms
64 bytes from 8.8.8.8: seq=4 ttl=42 time=55.839 ms
64 bytes from 8.8.8.8: seq=5 ttl=42 time=83.197 ms

 

//go:nosplit
func bluepillHandler(context unsafe.Pointer) {
    // Sanitize the registers; interrupts must always be disabled.
    c := bluepillArchEnter(bluepillArchContext(context))

    // Mark this as guest mode.
    switch atomic.SwapUint32(&c.state, vCPUGuest|vCPUUser) {
    case vCPUUser: // Expected case.
    case vCPUUser | vCPUWaiter:
        c.notify()
    default:
        throw("invalid state")
    }

    for {
        _, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(c.fd), _KVM_RUN, 0) // escapes: no.
        switch errno {
        case 0: // Expected case.
        case syscall.EINTR:
            // First, we process whatever pending signal
            // interrupted KVM. Since we‘re in a signal handler
            // currently, all signals are masked and the signal
            // must have been delivered directly to this thread.
            timeout := syscall.Timespec{}
            sig, _, errno := syscall.RawSyscall6( // escapes: no.
                syscall.SYS_RT_SIGTIMEDWAIT,
                uintptr(unsafe.Pointer(&bounceSignalMask)),
                0,                                 // siginfo.
                uintptr(unsafe.Pointer(&timeout)), // timeout.
                8,                                 // sigset size.
                0, 0)
            if errno == syscall.EAGAIN {
                continue
            }
            if errno != 0 {
                throw("error waiting for pending signal")
            }
            if sig != uintptr(bounceSignal) {
                throw("unexpected signal")
            }

            // Check whether the current state of the vCPU is ready
            // for interrupt injection. Because we don‘t have a
            // PIC, we can‘t inject an interrupt while they are
            // masked. We need to request a window if it‘s not
            // ready.
            if bluepillReadyStopGuest(c) {
                // Force injection below; the vCPU is ready.
                c.runData.exitReason = _KVM_EXIT_IRQ_WINDOW_OPEN
            } else {
                c.runData.requestInterruptWindow = 1
                continue // Rerun vCPU.
            }
        case syscall.EFAULT:
            // If a fault is not serviceable due to the host
            // backing pages having page permissions, instead of an
            // MMIO exit we receive EFAULT from the run ioctl. We
            // always inject an NMI here since we may be in kernel
            // mode and have interrupts disabled.
            bluepillSigBus(c)
            continue // Rerun vCPU.
        case syscall.ENOSYS:
            bluepillHandleEnosys(c)
            continue
        default:
            throw("run failed")
        }

        switch c.runData.exitReason {
        case _KVM_EXIT_EXCEPTION:
            c.die(bluepillArchContext(context), "exception")
            return
        case _KVM_EXIT_IO:
            c.die(bluepillArchContext(context), "I/O")
            return
        case _KVM_EXIT_INTERNAL_ERROR:
            // An internal error is typically thrown when emulation
            // fails. This can occur via the MMIO path below (and
            // it might fail because we have multiple regions that
            // are not mapped). We would actually prefer that no
            // emulation occur, and don‘t mind at all if it fails.
        case _KVM_EXIT_HYPERCALL:
            c.die(bluepillArchContext(context), "hypercall")
            return
        case _KVM_EXIT_DEBUG:
            c.die(bluepillArchContext(context), "debug")
            return
        case _KVM_EXIT_HLT:
            bluepillGuestExit(c, context)
            return
        case _KVM_EXIT_MMIO:
            physical := uintptr(c.runData.data[0])
            if getHypercallID(physical) == _KVM_HYPERCALL_VMEXIT {
                bluepillGuestExit(c, context)
                return
            }

            // Increment the fault count.
            atomic.AddUint32(&c.faults, 1)

            // For MMIO, the physical address is the first data item.
            physical = uintptr(c.runData.data[0])
            virtual, ok := handleBluepillFault(c.machine, physical, physicalRegions, _KVM_MEM_FLAGS_NONE)
            if !ok {
                c.die(bluepillArchContext(context), "invalid physical address")
                return
            }

            // We now need to fill in the data appropriately. KVM
            // expects us to provide the result of the given MMIO
            // operation in the runData struct. This is safe
            // because, if a fault occurs here, the same fault
            // would have occurred in guest mode. The kernel should
            // not create invalid page table mappings.
            data := (*[8]byte)(unsafe.Pointer(&c.runData.data[1]))
            length := (uintptr)((uint32)(c.runData.data[2]))
            write := (uint8)(((c.runData.data[2] >> 32) & 0xff)) != 0
            for i := uintptr(0); i < length; i++ {
                b := bytePtr(uintptr(virtual) + i)
                if write {
                    // Write to the given address.
                    *b = data[i]
                } else {
                    // Read from the given address.
                    data[i] = *b
                }
            }
        case _KVM_EXIT_IRQ_WINDOW_OPEN:
            bluepillStopGuest(c)
        case _KVM_EXIT_SHUTDOWN:
            c.die(bluepillArchContext(context), "shutdown")
            return
        case _KVM_EXIT_FAIL_ENTRY:
            c.die(bluepillArchContext(context), "entry failed")
            return
        default:
            bluepillArchHandleExit(c, context)
            return
        }
    }
}

 

 

 

 

root@cloud:/mycontainer# dlv attach 928771
Type help for list of commands.
(dlv) b bluepillHandler
Breakpoint 1 set at 0x87b300 for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:91
(dlv) c
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:91 (hits goroutine(276):1 total:1) (PC: 0x87b300)
Warning: debugging optimized function
(dlv) bt
 0  0x000000000087b300 in gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler
    at pkg/sentry/platform/kvm/bluepill_unsafe.go:91
 1  0x0000000000881bec in ???
    at ?:-1
 2  0x0000ffff82bfe598 in ???
    at ?:-1
 3  0x000000000087f514 in gvisor.dev/gvisor/pkg/sentry/platform/kvm.(*vCPU).SwitchToUser
    at pkg/sentry/platform/kvm/machine_arm64_unsafe.go:249
 4  0x00000000009e5f89 in ???
    at ?:-1
 5  0x000000000087bb1c in gvisor.dev/gvisor/pkg/sentry/platform/kvm.(*context).Switch
    at pkg/sentry/platform/kvm/context.go:75
 6  0x00000040005fc000 in ???
    at ?:-1
 7  0x0000000000517d9c in gvisor.dev/gvisor/pkg/sentry/kernel.(*Task).run
    at pkg/sentry/kernel/task_run.go:97
 8  0x00000040007a73f0 in ???
    at ?:-1
 9  0x0000000000077c84 in runtime.goexit
    at src/runtime/asm_arm64.s:1136
    error: Undefined return address at 0x77c84
(truncated)
(dlv) s
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:58 (PC: 0x87b30c)
Warning: debugging optimized function
(dlv) list
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:58 (PC: 0x87b30c)
Warning: debugging optimized function
Command failed: open pkg/sentry/platform/kvm/bluepill_unsafe.go: no such file or directory
(dlv) quit
Would you like to kill the process? [Y/n] n
root@cloud:/mycontainer# dlv attach 928771
Type help for list of commands.
(dlv) b bluepill_unsafe.go:105
Breakpoint 1 set at 0x87b34c for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105
(dlv) c
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105 (hits goroutine(252):1 total:1) (PC: 0x87b34c)
Warning: debugging optimized function
(dlv) bt
0  0x000000000087b34c in gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler
   at pkg/sentry/platform/kvm/bluepill_unsafe.go:105
1  0x0000000000881bec in ???
   at ?:-1
2  0x0000ffff82bfe598 in ???
   at ?:-1
3  0x000000000087f514 in gvisor.dev/gvisor/pkg/sentry/platform/kvm.(*vCPU).SwitchToUser
   at pkg/sentry/platform/kvm/machine_arm64_unsafe.go:249
(dlv) p errno
Command failed: could not find symbol value for errno
(dlv) n
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:106 (PC: 0x87b370)
Warning: debugging optimized function
(dlv) p errno
0
(dlv) p c.runData.exitReason
6
(dlv) p c.runData
*gvisor.dev/gvisor/pkg/sentry/platform/kvm.runData {
        requestInterruptWindow: 0,
        _: [7]uint8 [0,0,0,0,0,0,0],
        exitReason: 6,
        readyForInterruptInjection: 0,
        ifFlag: 0,
        _: [2]uint8 [0,0],
        cr8: 0,
        apicBase: 0,
        data: [32]uint64 [8882176,0,4294967304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],}
(dlv) clearall
Breakpoint 1 cleared at 0x87b34c for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105
(dlv) quit
Would you like to kill the process? [Y/n] y
root@cloud:/mycontainer# 

 

exitReason: 6

// KVM exit reasons.
const (
        _KVM_EXIT_EXCEPTION       = 0x1
        _KVM_EXIT_IO              = 0x2
        _KVM_EXIT_HYPERCALL       = 0x3
        _KVM_EXIT_DEBUG           = 0x4
        _KVM_EXIT_HLT             = 0x5
        _KVM_EXIT_MMIO            = 0x6
        _KVM_EXIT_IRQ_WINDOW_OPEN = 0x7
        _KVM_EXIT_SHUTDOWN        = 0x8
        _KVM_EXIT_FAIL_ENTRY      = 0x9
        _KVM_EXIT_INTERNAL_ERROR  = 0x11
        _KVM_EXIT_SYSTEM_EVENT    = 0x18
        _KVM_EXIT_ARM_NISV        = 0x1c
)

 

 

 

root@cloud:/mycontainer# dlv attach 928771
could not attach to pid 928771: no such process
root@cloud:/mycontainer# dlv attach 929197
Type help for list of commands.
(dlv) b bluepill_unsafe.go:105
Breakpoint 1 set at 0x87b34c for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105
(dlv) c
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105 (hits goroutine(224):1 total:1) (PC: 0x87b34c)
Warning: debugging optimized function
(dlv) p context
unsafe.Pointer(0x40006a0e20)
(dlv) p *context
Command failed: expression "context" (unsafe.Pointer) can not be dereferenced
(dlv) p c
*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU {
        CPU: gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPU {
                self: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPU")(0x40004ff000),
                kernel: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.Kernel")(0x4000323a18),
                CPUArchState: (*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPUArchState")(0x40004ff010),
                registers: (*"gvisor.dev/gvisor/pkg/sentry/arch.Registers")(0x40004ff258),
                hooks: gvisor.dev/gvisor/pkg/sentry/platform/ring0.Hooks(*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU) ...,},
        id: 0,
        fd: 7,
        tid: 21,
        userExits: 14,
        guestExits: 11,
        faults: 0,
        state: 3,
        runData: *gvisor.dev/gvisor/pkg/sentry/platform/kvm.runData {
                requestInterruptWindow: 0,
                _: [7]uint8 [0,0,0,0,0,0,0],
                exitReason: 6,
                readyForInterruptInjection: 0,
                ifFlag: 0,
                _: [2]uint8 [0,0],
                cr8: 0,
                apicBase: 0,
                data: [32]uint64 [8882176,0,4294967304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],},
        machine: *gvisor.dev/gvisor/pkg/sentry/platform/kvm.machine {
                fd: 23,
                nextSlot: 17,
                upperSharedPageTables: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables.PageTables")(0x4000124280),
                kernel: (*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.Kernel")(0x4000323a18),
                mu: (*"gvisor.dev/gvisor/pkg/sync.RWMutex")(0x4000323a28),
                available: (*sync.Cond)(0x4000323a40),
                vCPUsByTID: map[uint64]*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU [...],
                vCPUsByID: []*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU len: 512, cap: 512, [
                        *(*"gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU")(0x40004ff000),
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        ...+448 more
                ],
                maxVCPUs: 512,
                maxSlots: 512,
                usedSlots: []uintptr len: 512, cap: 512, [65536,10092544,1096804425728,1096804954112,1097341366272,1097408417792,1097416798208,21823488,274877906944,1096766996480,1096804950016,1097341362176,1097408413696,1097416794112,1097417842688,1099348434944,1093521661952,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+448 more],
                nextID: 1,},
        active: gvisor.dev/gvisor/pkg/sentry/platform/kvm.atomicAddressSpace {pointer: unsafe.Pointer(0x400021c5e0)},
        vCPUArchState: gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPUArchState {
                PCIDs: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables.PCIDs")(0x400014cba0),
                floatingPointState: *0,},
        dieState: gvisor.dev/gvisor/pkg/sentry/platform/kvm.dieState {
                message: "",
                guestRegs: (*"gvisor.dev/gvisor/pkg/sentry/platform/kvm.userRegs")(0x40004ff3e8),},}
(dlv) p c.state
3
(dlv)  b bluepill_unsafe.go:105-6
Command failed: Malformed breakpoint location "bluepill_unsafe.go:105-6" at 19: line offset negative or not a number
(dlv)  b bluepill_unsafe.go:106
Breakpoint 2 set at 0x87b370 for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:106
(dlv) c
> gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:106 (hits goroutine(224):1 total:1) (PC: 0x87b370)
Warning: debugging optimized function
(dlv) p c.state
3
(dlv) p c
*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU {
        CPU: gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPU {
                self: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPU")(0x40004ff000),
                kernel: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.Kernel")(0x4000323a18),
                CPUArchState: (*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.CPUArchState")(0x40004ff010),
                registers: (*"gvisor.dev/gvisor/pkg/sentry/arch.Registers")(0x40004ff258),
                hooks: gvisor.dev/gvisor/pkg/sentry/platform/ring0.Hooks(*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU) ...,},
        id: 0,
        fd: 7,
        tid: 21,
        userExits: 14,
        guestExits: 11,
        faults: 0,
        state: 3,
        runData: *gvisor.dev/gvisor/pkg/sentry/platform/kvm.runData {
                requestInterruptWindow: 0,
                _: [7]uint8 [0,0,0,0,0,0,0],
                exitReason: 6,
                readyForInterruptInjection: 0,
                ifFlag: 0,
                _: [2]uint8 [0,0],
                cr8: 0,
                apicBase: 0,
                data: [32]uint64 [8882176,0,4294967304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],},
        machine: *gvisor.dev/gvisor/pkg/sentry/platform/kvm.machine {
                fd: 23,
                nextSlot: 17,
                upperSharedPageTables: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables.PageTables")(0x4000124280),
                kernel: (*"gvisor.dev/gvisor/pkg/sentry/platform/ring0.Kernel")(0x4000323a18),
                mu: (*"gvisor.dev/gvisor/pkg/sync.RWMutex")(0x4000323a28),
                available: (*sync.Cond)(0x4000323a40),
                vCPUsByTID: map[uint64]*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU [...],
                vCPUsByID: []*gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU len: 512, cap: 512, [
                        *(*"gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPU")(0x40004ff000),
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        *nil,
                        ...+448 more
                ],
                maxVCPUs: 512,
                maxSlots: 512,
                usedSlots: []uintptr len: 512, cap: 512, [65536,10092544,1096804425728,1096804954112,1097341366272,1097408417792,1097416798208,21823488,274877906944,1096766996480,1096804950016,1097341362176,1097408413696,1097416794112,1097417842688,1099348434944,1093521661952,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+448 more],
                nextID: 1,},
        active: gvisor.dev/gvisor/pkg/sentry/platform/kvm.atomicAddressSpace {pointer: unsafe.Pointer(0x400021c5e0)},
        vCPUArchState: gvisor.dev/gvisor/pkg/sentry/platform/kvm.vCPUArchState {
                PCIDs: *(*"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables.PCIDs")(0x400014cba0),
                floatingPointState: *0,},
        dieState: gvisor.dev/gvisor/pkg/sentry/platform/kvm.dieState {
                message: "",
                guestRegs: (*"gvisor.dev/gvisor/pkg/sentry/platform/kvm.userRegs")(0x40004ff3e8),},}
(dlv) clearall
Breakpoint 1 cleared at 0x87b34c for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:105
Breakpoint 2 cleared at 0x87b370 for gvisor.dev/gvisor/pkg/sentry/platform/kvm.bluepillHandler() pkg/sentry/platform/kvm/bluepill_unsafe.go:106
(dlv) quit
Would you like to kill the process? [Y/n] n
root@cloud:/mycontainer# 

 

gvisor bluepillHandler

原文:https://www.cnblogs.com/dream397/p/14279097.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!