-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable kvm to support arm64 #919
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this contribution! I’ve love to get this merged.
My main feedback is simply that there’s a lot of duplication and copied code that should be common. I explain why this is not desirable below.
I don’t see major issues outside that, but I’d like to do another pass with those things fixed. I hope that makes sense.
pkg/sentry/platform/kvm/bluepill.go
Outdated
} | ||
|
||
// Setup the trampoline. | ||
dieArchSetup(c, context, &c.dieState.guestRegs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why move this function? I intentionally tried to split arch-specific bits into dieArchSetup already. It’s unclear to me what will need to change from the above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @amscanne,
_KVM_GET_REGS/_KVM_SET_REGS/_KVM_SET_SREGS are not supported on Arm64 platform, so getUserRegisters() & userRegs can't be used on Arm64 platform.
Currently, on Arm64 platform, we only use _KVM_SET_ONE_REG/_KVM_GET_ONE_REG to set/get registers.
Maybe I can use _KVM_GET_ONE_REG to simulate _KVM_GET_REGS on Arm platform.
dieArchSetup(c, context, &c.dieState.guestRegs) | ||
} | ||
|
||
func init() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment. Why is this arch-specific?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: it seems like it’s just the signal itself. I recommend just moving that into a constant in the arch-specific files. E.g.
const bluepillSignal = SIGILL
And just having this block refer to that signal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
Got it.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this isn't done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this isn't done?
Done. Sorry for it. :(
) | ||
|
||
var ( | ||
// bounceSignal is the signal used for bouncing KVM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are all common? I think you could move the common bits into bluepill.go. The bounce vector itself probably makes sense to keep as arch-specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @amscanne
The implementation for test case 'TestBounce' will be delivered in another PR.
'bounceSignal' , 'unceSignalMask' and 'bounce' are common.
And 'VirtualizationException' will be defined as a different value on Arm64.
Let me moved them into bluepill.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done?
9511548
to
813879f
Compare
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com> FUTURE_COPYBARA_INTEGRATE_REVIEW=#919 from lubinszARM:pr_kvm eedea52db451bf62722759009a9f14c54a69c55f PiperOrigin-RevId: 280695497
// | ||
//go:nosplit | ||
func (c *vCPU) die(context *arch.SignalContext64, msg string) { | ||
// TODO. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reference the ARM64 bug in TODOs and the same for all other TODO-s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pkg/sentry/platform/kvm/kvm_amd64.go
Outdated
@@ -211,3 +212,10 @@ type cpuidEntries struct { | |||
_ uint32 | |||
entries [_KVM_NR_CPUID_ENTRIES]cpuidEntry | |||
} | |||
|
|||
func updateGolbalOnce(fd int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Global
fallthrough | ||
case _ESR_SEGV_MAPERR_L2: | ||
fallthrough | ||
case _ESR_SEGV_MAPERR_L3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
case _ESR_SEGV_MAPERR_L0, _ESR_SEGV_MAPERR_L1, _ESR_SEGV_MAPERR_L2, _ESR_SEGV_MAPERR_L3:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
return (*(*[0xFFFFFF]byte)(unsafe.Pointer(p & ^uintptr(syscall.Getpagesize()-1))))[:syscall.Getpagesize()] | ||
} | ||
|
||
func RawMemoryAccessWithReflect(p uintptr) []byte { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this exist, it is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
return (*(*[0x800]byte)(unsafe.Pointer(p)))[:] | ||
} | ||
|
||
// Work around: move ring0.Vectors() into the address with 11-bits alignment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function needs much better explanation of what it does, why it exists, and ideally avoid rewriting the binary...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
|
||
page = getPageWithReflect(toLocation + 4096) | ||
if err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove PROT_WRITE before exiting from this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com> FUTURE_COPYBARA_INTEGRATE_REVIEW=#919 from lubinszARM:pr_kvm eedea52db451bf62722759009a9f14c54a69c55f PiperOrigin-RevId: 280695497
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com> FUTURE_COPYBARA_INTEGRATE_REVIEW=#919 from lubinszARM:pr_kvm 0241d74f2006b408b79a21105bd428dbeaa463a7 PiperOrigin-RevId: 280691360
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com> FUTURE_COPYBARA_INTEGRATE_REVIEW=#919 from lubinszARM:pr_kvm eedea52db451bf62722759009a9f14c54a69c55f PiperOrigin-RevId: 280695497
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @lubinszARM, it looks like you may have forgotten to push the latest version of this with fixes to @amscanne's comments?
dieArchSetup(c, context, &c.dieState.guestRegs) | ||
} | ||
|
||
func init() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this isn't done?
) | ||
|
||
var ( | ||
// bounceSignal is the signal used for bouncing KVM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done?
} | ||
|
||
//go:nosplit | ||
func dieArchSetup(c *vCPU, context *arch.SignalContext64, guestRegs *userRegs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done?
pkg/sentry/platform/kvm/kvm_amd64.go
Outdated
@@ -211,3 +212,10 @@ type cpuidEntries struct { | |||
_ uint32 | |||
entries [_KVM_NR_CPUID_ENTRIES]cpuidEntry | |||
} | |||
|
|||
func UpdateGolbalOnce(fd int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Global is misspelled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
cd4f4cc
to
563a492
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Sorry for it.
pkg/sentry/platform/kvm/kvm_amd64.go
Outdated
@@ -211,3 +212,10 @@ type cpuidEntries struct { | |||
_ uint32 | |||
entries [_KVM_NR_CPUID_ENTRIES]cpuidEntry | |||
} | |||
|
|||
func UpdateGolbalOnce(fd int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
dieArchSetup(c, context, &c.dieState.guestRegs) | ||
} | ||
|
||
func init() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this isn't done?
Done. Sorry for it. :(
} | ||
|
||
//go:nosplit | ||
func dieArchSetup(c *vCPU, context *arch.SignalContext64, guestRegs *userRegs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done?
Done. Please check it. Thanks.
offset = 1<<11 - offset | ||
} | ||
|
||
toLocation := fromLocation + offset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we ensure that this function doesn't clobber some other code at toLocation? It seems like ring0.Vectors should have something like a page of dummy data to reserve the space it needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we ensure that this function doesn't clobber some other code at toLocation? It seems like ring0.Vectors should have something like a page of dummy data to reserve the space it needs.
Hi @prattmic
In fact, the total size of 'exception-vectors-table' for Arm64 is required as 2K, please see the code of 'ENTRY(vectors)' in kernel(arch/arm64/kernel/entry.s) as reference.
For gvisor, I defined the function of 'exception-vectors-table' as 4K size. Please see the code in ring0/entry_arm64.s: Vectors(SB). I filled the 2nd 2K part with NOP(no operation) instructions.
And in the function of 'updateVectorTable()', I only memmove and modify the first 2K part of the binary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I understand now. Could you add a comment to that function explaining the purpose of the extra NOPs? (In a separate PR, this one looks good for merging).
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com>
There are 4 jobs were finished in this package: 1, Virtual machine initialization. 2, Bluepill implementation. 3, Move ring0.Vectors() into the address with 11-bits alignment. 4, Basic support for "SwitchToUser". Signed-off-by: Bin Lu <bin.lu@arm.com> COPYBARA_INTEGRATE_REVIEW=#919 from lubinszARM:pr_kvm eedea52db451bf62722759009a9f14c54a69c55f PiperOrigin-RevId: 285501256
There are 4 jobs were finished in this package:
1, Virtual machine initialization.
2, Bluepill implementation.
3, Move ring0.Vectors() into the address with 11-bits alignment.
4, Basic support for "SwitchToUser".
Signed-off-by: Bin Lu bin.lu@arm.com