Skip to content

Commit ca8d05a

Browse files
avagingvisor-bot
authored andcommitted
platform/kvm: refactor handleBluepillFault to reduce stack usage
PiperOrigin-RevId: 681217279
1 parent b99fd87 commit ca8d05a

File tree

8 files changed

+22
-76
lines changed

8 files changed

+22
-76
lines changed

pkg/sentry/platform/kvm/BUILD

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,6 @@ config_setting(
2424
},
2525
)
2626

27-
# @unused
28-
glaze_ignore = [
29-
"seccomp_mmap_dbg.go",
30-
"seccomp_mmap_real.go",
31-
]
32-
33-
# Use either seccomp_mmap_dbg.go or seccomp_mmap_real.go as seccomp_mmap.go.
34-
genrule(
35-
name = "seccomp_mmap",
36-
srcs = select({
37-
":debug_build": ["seccomp_mmap_dbg.go"],
38-
"//conditions:default": ["seccomp_mmap_real.go"],
39-
}),
40-
outs = ["seccomp_mmap_unsafe.go"],
41-
cmd = "cat < $(SRCS) > $(OUTS)",
42-
)
43-
4427
go_library(
4528
name = "kvm",
4629
srcs = [

pkg/sentry/platform/kvm/address_space.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (as *addressSpace) mapLocked(addr hostarch.Addr, m hostMapEntry, at hostarc
121121
// not have physical mappings, the KVM module may inject
122122
// spurious exceptions when emulation fails (i.e. it tries to
123123
// emulate because the RIP is pointed at those pages).
124-
as.machine.mapPhysical(physical, length, physicalRegions)
124+
as.machine.mapPhysical(physical, length)
125125

126126
// Install the page table mappings. Note that the ordering is
127127
// important; if the pagetable mappings were installed before

pkg/sentry/platform/kvm/bluepill_allocator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (a *allocator) PhysicalFor(ptes *pagetables.PTEs) uintptr {
7373
//
7474
//go:nosplit
7575
func (a *allocator) LookupPTEs(physical uintptr) *pagetables.PTEs {
76-
virtualStart, physicalStart, _, pr := calculateBluepillFault(physical, physicalRegions)
76+
virtualStart, physicalStart, _, pr := calculateBluepillFault(physical)
7777
if pr == nil {
7878
panic(fmt.Sprintf("LookupPTEs failed for 0x%x", physical)) // escapes: panic.
7979
}

pkg/sentry/platform/kvm/bluepill_fault.go

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ func yield() {
4747
// calculateBluepillFault calculates the fault address range.
4848
//
4949
//go:nosplit
50-
func calculateBluepillFault(physical uintptr, phyRegions []physicalRegion) (virtualStart, physicalStart, length uintptr, pr *physicalRegion) {
50+
func calculateBluepillFault(physical uintptr) (virtualStart, physicalStart, length uintptr, pr *physicalRegion) {
5151
alignedPhysical := physical &^ uintptr(hostarch.PageSize-1)
52-
for i, pr := range phyRegions {
52+
for i, pr := range physicalRegions {
5353
end := pr.physical + pr.length
5454
if physical < pr.physical || physical >= end {
5555
continue
@@ -63,27 +63,14 @@ func calculateBluepillFault(physical uintptr, phyRegions []physicalRegion) (virt
6363
physicalEnd = end
6464
}
6565
length = physicalEnd - physicalStart
66-
return virtualStart, physicalStart, length, &phyRegions[i]
66+
return virtualStart, physicalStart, length, &physicalRegions[i]
6767
}
6868

6969
return 0, 0, 0, nil
7070
}
7171

72-
// handleBluepillFault handles a physical fault.
73-
//
74-
// The corresponding virtual address is returned. This may throw on error.
75-
//
7672
//go:nosplit
77-
func handleBluepillFault(m *machine, physical uintptr, phyRegions []physicalRegion) (uintptr, bool) {
78-
// Paging fault: we need to map the underlying physical pages for this
79-
// fault. This all has to be done in this function because we're in a
80-
// signal handler context. (We can't call any functions that might
81-
// split the stack.)
82-
virtualStart, physicalStart, length, pr := calculateBluepillFault(physical, phyRegions)
83-
if pr == nil {
84-
return 0, false
85-
}
86-
73+
func (m *machine) mapMemorySlot(virtualStart, physicalStart, length uintptr, readOnly bool) {
8774
// Set the KVM slot.
8875
//
8976
// First, we need to acquire the exclusive right to set a slot. See
@@ -94,7 +81,7 @@ func handleBluepillFault(m *machine, physical uintptr, phyRegions []physicalRegi
9481
slot = m.nextSlot.Swap(^uint32(0))
9582
}
9683
flags := _KVM_MEM_FLAGS_NONE
97-
if pr.readOnly {
84+
if readOnly {
9885
flags |= _KVM_MEM_READONLY
9986
}
10087
errno := m.setMemoryRegion(int(slot), physicalStart, length, virtualStart, flags)
@@ -106,7 +93,7 @@ func handleBluepillFault(m *machine, physical uintptr, phyRegions []physicalRegi
10693
// Successfully added region; we can increment nextSlot and
10794
// allow another set to proceed here.
10895
m.nextSlot.Store(slot + 1)
109-
return virtualStart + (physical - physicalStart), true
96+
return
11097
}
11198

11299
// Release our slot (still available).
@@ -117,16 +104,17 @@ func handleBluepillFault(m *machine, physical uintptr, phyRegions []physicalRegi
117104
// The region already exists. It's possible that we raced with
118105
// another vCPU here. We just revert nextSlot and return true,
119106
// because this must have been satisfied by some other vCPU.
120-
return virtualStart + (physical - physicalStart), true
107+
return
121108
case unix.EINVAL:
122109
throw("set memory region failed; out of slots")
123110
case unix.ENOMEM:
124111
throw("set memory region failed: out of memory")
125112
case unix.EFAULT:
126113
throw("set memory region failed: invalid physical range")
127114
default:
115+
printHex([]byte("set memory region failed:"), uint64(errno))
128116
throw("set memory region failed: unknown reason")
129117
}
130118

131-
panic("unreachable")
119+
throw("unreachable")
132120
}

pkg/sentry/platform/kvm/machine.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ func newMachine(vm int) (*machine, error) {
371371
}
372372

373373
// Ensure the physical range is mapped.
374-
m.mapPhysical(physical, length, physicalRegions)
374+
m.mapPhysical(physical, length)
375375
virtual += length
376376
}
377377
}
@@ -396,7 +396,7 @@ func newMachine(vm int) (*machine, error) {
396396
})
397397
if mapEntireAddressSpace {
398398
for _, r := range physicalRegions {
399-
m.mapPhysical(r.physical, r.length, physicalRegions)
399+
m.mapPhysical(r.physical, r.length)
400400
}
401401
}
402402
enableAsyncPreemption()
@@ -438,19 +438,17 @@ func (m *machine) hasSlot(physical uintptr) bool {
438438
// This throws on error.
439439
//
440440
//go:nosplit
441-
func (m *machine) mapPhysical(physical, length uintptr, phyRegions []physicalRegion) {
441+
func (m *machine) mapPhysical(physical, length uintptr) {
442442
for end := physical + length; physical < end; {
443-
_, physicalStart, length, pr := calculateBluepillFault(physical, phyRegions)
443+
virtualStart, physicalStart, length, pr := calculateBluepillFault(physical)
444444
if pr == nil {
445445
// Should never happen.
446446
throw("mapPhysical on unknown physical address")
447447
}
448448

449449
// Is this already mapped? Check the usedSlots.
450450
if !m.hasSlot(physicalStart) {
451-
if _, ok := handleBluepillFault(m, physical, phyRegions); !ok {
452-
throw("handleBluepillFault failed")
453-
}
451+
m.mapMemorySlot(virtualStart, physicalStart, length, pr.readOnly)
454452
}
455453

456454
// Move to the next chunk.

pkg/sentry/platform/kvm/machine_amd64_unsafe.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,11 @@ func seccompMmapSyscall(context unsafe.Pointer) (uintptr, uintptr, unix.Errno) {
192192
// MAP_DENYWRITE is deprecated and ignored by kernel. We use it only for seccomp filters.
193193
addr, e := hostsyscall.RawSyscall6(uintptr(ctx.Rax), uintptr(ctx.Rdi), uintptr(ctx.Rsi),
194194
uintptr(ctx.Rdx), uintptr(ctx.R10)|unix.MAP_DENYWRITE, uintptr(ctx.R8), uintptr(ctx.R9))
195-
ctx.Rax = uint64(addr)
195+
if e != 0 {
196+
ctx.Rax = uint64(-e)
197+
} else {
198+
ctx.Rax = uint64(addr)
199+
}
196200

197201
return addr, uintptr(ctx.Rsi), unix.Errno(e)
198202
}

pkg/sentry/platform/kvm/seccomp_mmap_dbg.go

Lines changed: 0 additions & 27 deletions
This file was deleted.

pkg/sentry/platform/kvm/seccomp_mmap_real.go renamed to pkg/sentry/platform/kvm/seccomp_mmap_unsafe.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func seccompMmapHandler(context unsafe.Pointer) {
6161
}
6262

6363
// Ensure the physical range is mapped.
64-
m.mapPhysical(physical, length, physicalRegions)
64+
m.mapPhysical(physical, length)
6565
virtual += length
6666
}
6767
}

0 commit comments

Comments
 (0)