summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBin Lu <bin.lu@arm.com>2020-03-04 04:20:36 -0500
committerBin Lu <bin.lu@arm.com>2020-03-12 05:57:47 -0400
commit7df936f359766618470ae31a7cbf1b761bd19b59 (patch)
treedb6971413c2861ce51aebbb435f493ba0261c503
parentef1219c1451a75916693a54ddad39d04cf763d90 (diff)
passed the syscall test case 'alarm' on Arm64 platform
This issue was caused by 'restart_syscall'. The value of Register R0 should be stored after finishing sysemu. So that we can restore the value and restart syscall. Signed-off-by: Bin Lu <bin.lu@arm.com>
-rw-r--r--pkg/sentry/arch/arch_aarch64.go4
-rw-r--r--pkg/sentry/arch/syscalls_arm64.go10
2 files changed, 13 insertions, 1 deletions
diff --git a/pkg/sentry/arch/arch_aarch64.go b/pkg/sentry/arch/arch_aarch64.go
index 5053393c1..01940bca4 100644
--- a/pkg/sentry/arch/arch_aarch64.go
+++ b/pkg/sentry/arch/arch_aarch64.go
@@ -97,6 +97,9 @@ type State struct {
// FeatureSet is a pointer to the currently active feature set.
FeatureSet *cpuid.FeatureSet
+
+ // OrigR0 stores the value of register R0.
+ OrigR0 uint64
}
// Proto returns a protobuf representation of the system registers in State.
@@ -146,6 +149,7 @@ func (s *State) Fork() State {
Regs: s.Regs,
aarch64FPState: s.aarch64FPState.fork(),
FeatureSet: s.FeatureSet,
+ OrigR0: s.OrigR0,
}
}
diff --git a/pkg/sentry/arch/syscalls_arm64.go b/pkg/sentry/arch/syscalls_arm64.go
index 00d5ef461..dc13b6124 100644
--- a/pkg/sentry/arch/syscalls_arm64.go
+++ b/pkg/sentry/arch/syscalls_arm64.go
@@ -50,13 +50,21 @@ func (c *context64) SyscallArgs() SyscallArguments {
}
// RestartSyscall implements Context.RestartSyscall.
+// Prepare for system call restart, OrigR0 will be restored to R0.
+// Please see the linux code as reference:
+// arch/arm64/kernel/signal.c:do_signal()
func (c *context64) RestartSyscall() {
c.Regs.Pc -= SyscallWidth
- c.Regs.Regs[8] = uint64(restartSyscallNr)
+ // R0 will be backed up into OrigR0 when entering doSyscall().
+ // Please see the linux code as reference:
+ // arch/arm64/kernel/syscall.c:el0_svc_common().
+ // Here we restore it back.
+ c.Regs.Regs[0] = uint64(c.OrigR0)
}
// RestartSyscallWithRestartBlock implements Context.RestartSyscallWithRestartBlock.
func (c *context64) RestartSyscallWithRestartBlock() {
c.Regs.Pc -= SyscallWidth
+ c.Regs.Regs[0] = uint64(c.OrigR0)
c.Regs.Regs[8] = uint64(restartSyscallNr)
}