~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/cpus.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/gdb/linux/cpus.py (Version linux-6.12-rc7) and /scripts/gdb/linux/cpus.py (Version linux-6.10.14)


  1 #                                                   1 #
  2 # gdb helper commands and functions for Linux       2 # gdb helper commands and functions for Linux kernel debugging
  3 #                                                   3 #
  4 #  per-cpu tools                                    4 #  per-cpu tools
  5 #                                                   5 #
  6 # Copyright (c) Siemens AG, 2011-2013               6 # Copyright (c) Siemens AG, 2011-2013
  7 #                                                   7 #
  8 # Authors:                                          8 # Authors:
  9 #  Jan Kiszka <jan.kiszka@siemens.com>               9 #  Jan Kiszka <jan.kiszka@siemens.com>
 10 #                                                  10 #
 11 # This work is licensed under the terms of the     11 # This work is licensed under the terms of the GNU GPL version 2.
 12 #                                                  12 #
 13                                                    13 
 14 import gdb                                         14 import gdb
 15                                                    15 
 16 from linux import tasks, utils                     16 from linux import tasks, utils
 17                                                    17 
 18                                                    18 
 19 task_type = utils.CachedType("struct task_stru     19 task_type = utils.CachedType("struct task_struct")
 20                                                    20 
 21                                                    21 
 22 MAX_CPUS = 4096                                    22 MAX_CPUS = 4096
 23                                                    23 
 24                                                    24 
 25 def get_current_cpu():                             25 def get_current_cpu():
 26     if utils.get_gdbserver_type() == utils.GDB     26     if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU:
 27         return gdb.selected_thread().num - 1       27         return gdb.selected_thread().num - 1
 28     elif utils.get_gdbserver_type() == utils.G     28     elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB:
 29         return gdb.parse_and_eval("kgdb_active     29         return gdb.parse_and_eval("kgdb_active.counter")
 30     else:                                          30     else:
 31         raise gdb.GdbError("Sorry, obtaining t     31         raise gdb.GdbError("Sorry, obtaining the current CPU is not yet "
 32                            "supported with thi     32                            "supported with this gdb server.")
 33                                                    33 
 34                                                    34 
 35 def per_cpu(var_ptr, cpu):                         35 def per_cpu(var_ptr, cpu):
 36     if cpu == -1:                                  36     if cpu == -1:
 37         cpu = get_current_cpu()                    37         cpu = get_current_cpu()
 38     if utils.is_target_arch("sparc:v9"):           38     if utils.is_target_arch("sparc:v9"):
 39         offset = gdb.parse_and_eval(               39         offset = gdb.parse_and_eval(
 40             "trap_block[{0}].__per_cpu_base".f     40             "trap_block[{0}].__per_cpu_base".format(str(cpu)))
 41     else:                                          41     else:
 42         try:                                       42         try:
 43             offset = gdb.parse_and_eval(           43             offset = gdb.parse_and_eval(
 44                 "__per_cpu_offset[{0}]".format     44                 "__per_cpu_offset[{0}]".format(str(cpu)))
 45         except gdb.error:                          45         except gdb.error:
 46             # !CONFIG_SMP case                     46             # !CONFIG_SMP case
 47             offset = 0                             47             offset = 0
 48     pointer = var_ptr.cast(utils.get_long_type     48     pointer = var_ptr.cast(utils.get_long_type()) + offset
 49     return pointer.cast(var_ptr.type).derefere     49     return pointer.cast(var_ptr.type).dereference()
 50                                                    50 
 51                                                    51 
 52 cpu_mask = {}                                      52 cpu_mask = {}
 53                                                    53 
 54                                                    54 
 55 def cpu_mask_invalidate(event):                    55 def cpu_mask_invalidate(event):
 56     global cpu_mask                                56     global cpu_mask
 57     cpu_mask = {}                                  57     cpu_mask = {}
 58     gdb.events.stop.disconnect(cpu_mask_invali     58     gdb.events.stop.disconnect(cpu_mask_invalidate)
 59     if hasattr(gdb.events, 'new_objfile'):         59     if hasattr(gdb.events, 'new_objfile'):
 60         gdb.events.new_objfile.disconnect(cpu_     60         gdb.events.new_objfile.disconnect(cpu_mask_invalidate)
 61                                                    61 
 62                                                    62 
 63 def cpu_list(mask_name):                           63 def cpu_list(mask_name):
 64     global cpu_mask                                64     global cpu_mask
 65     mask = None                                    65     mask = None
 66     if mask_name in cpu_mask:                      66     if mask_name in cpu_mask:
 67         mask = cpu_mask[mask_name]                 67         mask = cpu_mask[mask_name]
 68     if mask is None:                               68     if mask is None:
 69         mask = gdb.parse_and_eval(mask_name +      69         mask = gdb.parse_and_eval(mask_name + ".bits")
 70         if hasattr(gdb, 'events'):                 70         if hasattr(gdb, 'events'):
 71             cpu_mask[mask_name] = mask             71             cpu_mask[mask_name] = mask
 72             gdb.events.stop.connect(cpu_mask_i     72             gdb.events.stop.connect(cpu_mask_invalidate)
 73             if hasattr(gdb.events, 'new_objfil     73             if hasattr(gdb.events, 'new_objfile'):
 74                 gdb.events.new_objfile.connect     74                 gdb.events.new_objfile.connect(cpu_mask_invalidate)
 75     bits_per_entry = mask[0].type.sizeof * 8       75     bits_per_entry = mask[0].type.sizeof * 8
 76     num_entries = mask.type.sizeof * 8 / bits_     76     num_entries = mask.type.sizeof * 8 / bits_per_entry
 77     entry = -1                                     77     entry = -1
 78     bits = 0                                       78     bits = 0
 79                                                    79 
 80     while True:                                    80     while True:
 81         while bits == 0:                           81         while bits == 0:
 82             entry += 1                             82             entry += 1
 83             if entry == num_entries:               83             if entry == num_entries:
 84                 return                             84                 return
 85             bits = mask[entry]                     85             bits = mask[entry]
 86             if bits != 0:                          86             if bits != 0:
 87                 bit = 0                            87                 bit = 0
 88                 break                              88                 break
 89                                                    89 
 90         while bits & 1 == 0:                       90         while bits & 1 == 0:
 91             bits >>= 1                             91             bits >>= 1
 92             bit += 1                               92             bit += 1
 93                                                    93 
 94         cpu = entry * bits_per_entry + bit         94         cpu = entry * bits_per_entry + bit
 95                                                    95 
 96         bits >>= 1                                 96         bits >>= 1
 97         bit += 1                                   97         bit += 1
 98                                                    98 
 99         yield int(cpu)                             99         yield int(cpu)
100                                                   100 
101                                                   101 
102 def each_online_cpu():                            102 def each_online_cpu():
103     for cpu in cpu_list("__cpu_online_mask"):     103     for cpu in cpu_list("__cpu_online_mask"):
104         yield cpu                                 104         yield cpu
105                                                   105 
106                                                   106 
107 def each_present_cpu():                           107 def each_present_cpu():
108     for cpu in cpu_list("__cpu_present_mask"):    108     for cpu in cpu_list("__cpu_present_mask"):
109         yield cpu                                 109         yield cpu
110                                                   110 
111                                                   111 
112 def each_possible_cpu():                          112 def each_possible_cpu():
113     for cpu in cpu_list("__cpu_possible_mask")    113     for cpu in cpu_list("__cpu_possible_mask"):
114         yield cpu                                 114         yield cpu
115                                                   115 
116                                                   116 
117 def each_active_cpu():                            117 def each_active_cpu():
118     for cpu in cpu_list("__cpu_active_mask"):     118     for cpu in cpu_list("__cpu_active_mask"):
119         yield cpu                                 119         yield cpu
120                                                   120 
121                                                   121 
122 class LxCpus(gdb.Command):                        122 class LxCpus(gdb.Command):
123     """List CPU status arrays                     123     """List CPU status arrays
124                                                   124 
125 Displays the known state of each CPU based on     125 Displays the known state of each CPU based on the kernel masks
126 and can help identify the state of hotplugged     126 and can help identify the state of hotplugged CPUs"""
127                                                   127 
128     def __init__(self):                           128     def __init__(self):
129         super(LxCpus, self).__init__("lx-cpus"    129         super(LxCpus, self).__init__("lx-cpus", gdb.COMMAND_DATA)
130                                                   130 
131     def invoke(self, arg, from_tty):              131     def invoke(self, arg, from_tty):
132         gdb.write("Possible CPUs : {}\n".forma    132         gdb.write("Possible CPUs : {}\n".format(list(each_possible_cpu())))
133         gdb.write("Present CPUs  : {}\n".forma    133         gdb.write("Present CPUs  : {}\n".format(list(each_present_cpu())))
134         gdb.write("Online CPUs   : {}\n".forma    134         gdb.write("Online CPUs   : {}\n".format(list(each_online_cpu())))
135         gdb.write("Active CPUs   : {}\n".forma    135         gdb.write("Active CPUs   : {}\n".format(list(each_active_cpu())))
136                                                   136 
137                                                   137 
138 LxCpus()                                          138 LxCpus()
139                                                   139 
140                                                   140 
141 class PerCpu(gdb.Function):                       141 class PerCpu(gdb.Function):
142     """Return per-cpu variable.                   142     """Return per-cpu variable.
143                                                   143 
144 $lx_per_cpu("VAR"[, CPU]): Return the per-cpu     144 $lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the
145 given CPU number. If CPU is omitted, the CPU o    145 given CPU number. If CPU is omitted, the CPU of the current context is used.
146 Note that VAR has to be quoted as string."""      146 Note that VAR has to be quoted as string."""
147                                                   147 
148     def __init__(self):                           148     def __init__(self):
149         super(PerCpu, self).__init__("lx_per_c    149         super(PerCpu, self).__init__("lx_per_cpu")
150                                                   150 
151     def invoke(self, var, cpu=-1):                151     def invoke(self, var, cpu=-1):
152         return per_cpu(var.address, cpu)          152         return per_cpu(var.address, cpu)
153                                                   153 
154                                                   154 
155 PerCpu()                                          155 PerCpu()
156                                                   156 
157 def get_current_task(cpu):                        157 def get_current_task(cpu):
158     task_ptr_type = task_type.get_type().point    158     task_ptr_type = task_type.get_type().pointer()
159                                                   159 
160     if utils.is_target_arch("x86"):               160     if utils.is_target_arch("x86"):
161         if gdb.lookup_global_symbol("cpu_tasks    161         if gdb.lookup_global_symbol("cpu_tasks"):
162             # This is a UML kernel, which stor    162             # This is a UML kernel, which stores the current task
163             # differently than other x86 sub a    163             # differently than other x86 sub architectures
164             var_ptr = gdb.parse_and_eval("(str    164             var_ptr = gdb.parse_and_eval("(struct task_struct *)cpu_tasks[0].task")
165             return var_ptr.dereference()          165             return var_ptr.dereference()
166         else:                                     166         else:
167             var_ptr = gdb.parse_and_eval("&pcp    167             var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task")
168             return per_cpu(var_ptr, cpu).deref    168             return per_cpu(var_ptr, cpu).dereference()
169     elif utils.is_target_arch("aarch64"):         169     elif utils.is_target_arch("aarch64"):
170         current_task_addr = gdb.parse_and_eval    170         current_task_addr = gdb.parse_and_eval("$SP_EL0")
171         if (current_task_addr >> 63) != 0:        171         if (current_task_addr >> 63) != 0:
172             current_task = current_task_addr.c    172             current_task = current_task_addr.cast(task_ptr_type)
173             return current_task.dereference()     173             return current_task.dereference()
174         else:                                     174         else:
175             raise gdb.GdbError("Sorry, obtaini    175             raise gdb.GdbError("Sorry, obtaining the current task is not allowed "
176                                "while running     176                                "while running in userspace(EL0)")
177     elif utils.is_target_arch("riscv"):           177     elif utils.is_target_arch("riscv"):
178         current_tp = gdb.parse_and_eval("$tp")    178         current_tp = gdb.parse_and_eval("$tp")
179         scratch_reg = gdb.parse_and_eval("$ssc    179         scratch_reg = gdb.parse_and_eval("$sscratch")
180                                                   180 
181         # by default tp points to current task    181         # by default tp points to current task
182         current_task = current_tp.cast(task_pt    182         current_task = current_tp.cast(task_ptr_type)
183                                                   183 
184         # scratch register is set 0 in trap ha    184         # scratch register is set 0 in trap handler after entering kernel.
185         # When hart is in user mode, scratch r    185         # When hart is in user mode, scratch register is pointing to task_struct.
186         # and tp is used by user mode. So when    186         # and tp is used by user mode. So when scratch register holds larger value
187         # (negative address as ulong is larger    187         # (negative address as ulong is larger value) than tp, then use scratch register.
188         if (scratch_reg.cast(utils.get_ulong_t    188         if (scratch_reg.cast(utils.get_ulong_type()) > current_tp.cast(utils.get_ulong_type())):
189             current_task = scratch_reg.cast(ta    189             current_task = scratch_reg.cast(task_ptr_type)
190                                                   190 
191         return current_task.dereference()         191         return current_task.dereference()
192     else:                                         192     else:
193         raise gdb.GdbError("Sorry, obtaining t    193         raise gdb.GdbError("Sorry, obtaining the current task is not yet "
194                            "supported with thi    194                            "supported with this arch")
195                                                   195 
196 class LxCurrentFunc(gdb.Function):                196 class LxCurrentFunc(gdb.Function):
197     """Return current task.                       197     """Return current task.
198                                                   198 
199 $lx_current([CPU]): Return the per-cpu task va    199 $lx_current([CPU]): Return the per-cpu task variable for the given CPU
200 number. If CPU is omitted, the CPU of the curr    200 number. If CPU is omitted, the CPU of the current context is used."""
201                                                   201 
202     def __init__(self):                           202     def __init__(self):
203         super(LxCurrentFunc, self).__init__("l    203         super(LxCurrentFunc, self).__init__("lx_current")
204                                                   204 
205     def invoke(self, cpu=-1):                     205     def invoke(self, cpu=-1):
206         return get_current_task(cpu)              206         return get_current_task(cpu)
207                                                   207 
208                                                   208 
209 LxCurrentFunc()                                   209 LxCurrentFunc()
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php