arm64 kvm: add to ext_dabt injection support
If no vild syndrome(data abort outside memslots) was reported by kvm, let userspace to do the ext_dabt injection to bail out this issue. Signed-off-by: Robin Luk <lubin.lu@antgroup.com>
This commit is contained in:
parent
60ae6c4d83
commit
6a85d13ccf
|
@ -91,6 +91,13 @@ func bluepillSigBus(c *vCPU) {
|
|||
}
|
||||
}
|
||||
|
||||
// bluepillHandleEnosys is reponsible for handling enosys error.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillHandleEnosys(c *vCPU) {
|
||||
throw("run failed: ENOSYS")
|
||||
}
|
||||
|
||||
// bluepillReadyStopGuest checks whether the current vCPU is ready for interrupt injection.
|
||||
//
|
||||
//go:nosplit
|
||||
|
@ -126,3 +133,10 @@ func bluepillReadyStopGuest(c *vCPU) bool {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// bluepillArchHandleExit checks architecture specific exitcode.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillArchHandleExit(c *vCPU, context unsafe.Pointer) {
|
||||
c.die(bluepillArchContext(context), "unknown")
|
||||
}
|
||||
|
|
|
@ -42,6 +42,13 @@ var (
|
|||
sErrEsr: _ESR_ELx_SERR_NMI,
|
||||
},
|
||||
}
|
||||
|
||||
// vcpuExtDabt is the event of ext_dabt.
|
||||
vcpuExtDabt = kvmVcpuEvents{
|
||||
exception: exception{
|
||||
extDabtPending: 1,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// getTLS returns the value of TPIDR_EL0 register.
|
||||
|
|
|
@ -85,7 +85,7 @@ func bluepillStopGuest(c *vCPU) {
|
|||
uintptr(c.fd),
|
||||
_KVM_SET_VCPU_EVENTS,
|
||||
uintptr(unsafe.Pointer(&vcpuSErrBounce))); errno != 0 {
|
||||
throw("sErr injection failed")
|
||||
throw("bounce sErr injection failed")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,18 +93,54 @@ func bluepillStopGuest(c *vCPU) {
|
|||
//
|
||||
//go:nosplit
|
||||
func bluepillSigBus(c *vCPU) {
|
||||
// Host must support ARM64_HAS_RAS_EXTN.
|
||||
if _, _, errno := syscall.RawSyscall( // escapes: no.
|
||||
syscall.SYS_IOCTL,
|
||||
uintptr(c.fd),
|
||||
_KVM_SET_VCPU_EVENTS,
|
||||
uintptr(unsafe.Pointer(&vcpuSErrNMI))); errno != 0 {
|
||||
throw("sErr injection failed")
|
||||
if errno == syscall.EINVAL {
|
||||
throw("No ARM64_HAS_RAS_EXTN feature in host.")
|
||||
}
|
||||
throw("nmi sErr injection failed")
|
||||
}
|
||||
}
|
||||
|
||||
// bluepillExtDabt is reponsible for injecting external data abort.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillExtDabt(c *vCPU) {
|
||||
if _, _, errno := syscall.RawSyscall( // escapes: no.
|
||||
syscall.SYS_IOCTL,
|
||||
uintptr(c.fd),
|
||||
_KVM_SET_VCPU_EVENTS,
|
||||
uintptr(unsafe.Pointer(&vcpuExtDabt))); errno != 0 {
|
||||
throw("ext_dabt injection failed")
|
||||
}
|
||||
}
|
||||
|
||||
// bluepillHandleEnosys is reponsible for handling enosys error.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillHandleEnosys(c *vCPU) {
|
||||
bluepillExtDabt(c)
|
||||
}
|
||||
|
||||
// bluepillReadyStopGuest checks whether the current vCPU is ready for sError injection.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillReadyStopGuest(c *vCPU) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// bluepillArchHandleExit checks architecture specific exitcode.
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepillArchHandleExit(c *vCPU, context unsafe.Pointer) {
|
||||
switch c.runData.exitReason {
|
||||
case _KVM_EXIT_ARM_NISV:
|
||||
bluepillExtDabt(c)
|
||||
default:
|
||||
c.die(bluepillArchContext(context), "unknown")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,6 +148,9 @@ func bluepillHandler(context unsafe.Pointer) {
|
|||
// mode and have interrupts disabled.
|
||||
bluepillSigBus(c)
|
||||
continue // Rerun vCPU.
|
||||
case syscall.ENOSYS:
|
||||
bluepillHandleEnosys(c)
|
||||
continue
|
||||
default:
|
||||
throw("run failed")
|
||||
}
|
||||
|
@ -220,7 +223,7 @@ func bluepillHandler(context unsafe.Pointer) {
|
|||
c.die(bluepillArchContext(context), "entry failed")
|
||||
return
|
||||
default:
|
||||
c.die(bluepillArchContext(context), "unknown")
|
||||
bluepillArchHandleExit(c, context)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,10 +47,11 @@ type userRegs struct {
|
|||
}
|
||||
|
||||
type exception struct {
|
||||
sErrPending uint8
|
||||
sErrHasEsr uint8
|
||||
pad [6]uint8
|
||||
sErrEsr uint64
|
||||
sErrPending uint8
|
||||
sErrHasEsr uint8
|
||||
extDabtPending uint8
|
||||
pad [5]uint8
|
||||
sErrEsr uint64
|
||||
}
|
||||
|
||||
type kvmVcpuEvents struct {
|
||||
|
|
|
@ -56,6 +56,7 @@ const (
|
|||
_KVM_EXIT_FAIL_ENTRY = 0x9
|
||||
_KVM_EXIT_INTERNAL_ERROR = 0x11
|
||||
_KVM_EXIT_SYSTEM_EVENT = 0x18
|
||||
_KVM_EXIT_ARM_NISV = 0x1c
|
||||
)
|
||||
|
||||
// KVM capability options.
|
||||
|
|
Loading…
Reference in New Issue