~ [ 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-4.4.302)


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