@@ -11,53 +11,57 @@ target_ptr_t default_get_current_task_struct(CPUState *cpu)
11
11
target_ptr_t current_task_addr;
12
12
target_ptr_t ts;
13
13
14
- #ifdef TARGET_ARM
14
+ #ifdef TARGET_AARCH64
15
+ extern target_ptr_t spel0;
15
16
// aarch64
16
- if (((CPUARMState*) cpu->env_ptr )->aarch64 ) {
17
- // for kernel versions >= 4.10.0
18
- if (PROFILE_KVER_GE (ki, 4 , 10 , 0 )) {
19
- current_task_addr = ki.task .init_addr ;
20
-
21
- // for kernel versions between 3.7.0 and 4.9.257
22
- } else if (PROFILE_KVER_LT (ki, 4 , 10 , 0 ) && PROFILE_KVER_GE (ki, 3 , 7 , 0 )) {
23
- target_ptr_t kernel_sp = panda_current_ksp (cpu); // ((CPUARMState*) cpu->env_ptr)->sp_el[1];
24
- target_ptr_t task_thread_info = kernel_sp & ~(0x4000 -1 );
25
- current_task_addr = task_thread_info+0x10 ;
26
-
27
-
28
- // because some kernel versions use both per_cpu variables AND access the task_struct
29
- // via the thread_info struct, the default call to struct_get with the per_cpu_offset_0_addr can be incorrect
30
- err = struct_get (cpu, &ts, current_task_addr, 0 );
31
- assert (err == struct_get_ret_t ::SUCCESS && " failed to get current task struct" );
32
- fixupendian2 (ts);
33
- return ts;
34
- } else {
35
- assert (false && " cannot use kernel version older than 3.7" );
36
- }
37
-
38
- // arm32
39
- } else {
40
- target_ptr_t kernel_sp = panda_current_ksp (cpu);
41
-
42
- // XXX: This should use THREADINFO_MASK but that's hardcoded and wrong for my test system
43
- // We need to expose that as a part of the OSI config - See issue #651
44
- target_ptr_t task_thread_info = kernel_sp & ~(0x2000 -1 );
45
-
46
- // for kernel versions >= 5.18.0
47
- if (PROFILE_KVER_GE (ki, 5 , 18 , 0 )) {
48
- return task_thread_info;
49
- }
50
-
51
- current_task_addr=task_thread_info+0xC ;
52
-
17
+ if (PROFILE_KVER_GE (ki, 4 , 10 , 0 )){
18
+ // https://elixir.bootlin.com/linux/v4.10/source/arch/arm64/include/asm/current.h#L25
19
+ return spel0;
20
+ } else if (PROFILE_KVER_GE (ki, 4 , 6 , 0 )) {
21
+ // untested
22
+ // https://elixir.bootlin.com/linux/v4.6/source/arch/arm64/include/asm/thread_info.h#L79
23
+ target_ptr_t task_thread_info = spel0;
24
+ current_task_addr = task_thread_info+0x10 ;
25
+ err = struct_get (cpu, &ts, current_task_addr, 0 );
26
+ return ts;
27
+ } else if (PROFILE_KVER_GE (ki, 3 , 7 , 0 )) {
28
+ // https://elixir.bootlin.com/linux/v3.7/source/arch/arm64/include/asm/thread_info.h#L79
29
+ target_ptr_t kernel_sp = panda_current_ksp (cpu); // ((CPUARMState*) cpu->env_ptr)->sp_el[1];
30
+ target_ptr_t task_thread_info = kernel_sp & ~(0x4000 -1 );
31
+ current_task_addr = task_thread_info+0x10 ;
53
32
// because some kernel versions use both per_cpu variables AND access the task_struct
54
33
// via the thread_info struct, the default call to struct_get with the per_cpu_offset_0_addr can be incorrect
55
34
err = struct_get (cpu, &ts, current_task_addr, 0 );
56
35
assert (err == struct_get_ret_t ::SUCCESS && " failed to get current task struct" );
57
36
fixupendian2 (ts);
58
37
return ts;
38
+ } else {
39
+ // solid chance the above implemntation just works for older kernels
40
+ // see: https://elixir.bootlin.com/linux/v2.6.39.4/source/arch/arm/include/asm/thread_info.h#L92
41
+ assert (false && " cannot use kernel version older than 3.7" );
42
+ }
43
+ #elif defined(TARGET_ARM) && !defined(TARGET_AARCH64)
44
+ // arm32
45
+ target_ptr_t kernel_sp = panda_current_ksp (cpu);
59
46
47
+ // XXX: This should use THREADINFO_MASK but that's hardcoded and wrong for my test system
48
+ // We need to expose that as a part of the OSI config - See issue #651
49
+ target_ptr_t task_thread_info = kernel_sp & ~(0x2000 -1 );
50
+
51
+ // for kernel versions >= 5.18.0
52
+ if (PROFILE_KVER_GE (ki, 5 , 18 , 0 )) {
53
+ return task_thread_info;
60
54
}
55
+
56
+ current_task_addr=task_thread_info+0xC ;
57
+
58
+ // because some kernel versions use both per_cpu variables AND access the task_struct
59
+ // via the thread_info struct, the default call to struct_get with the per_cpu_offset_0_addr can be incorrect
60
+ err = struct_get (cpu, &ts, current_task_addr, 0 );
61
+ assert (err == struct_get_ret_t ::SUCCESS && " failed to get current task struct" );
62
+ fixupendian2 (ts);
63
+ return ts;
64
+
61
65
#elif defined(TARGET_MIPS)
62
66
// __current_thread_info is stored in KERNEL r28
63
67
// userspace clobbers it but kernel restores (somewhow?)
0 commit comments