Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Nov 2025 12:29:23 -0600
From:      Friedrich Doku <friedrichdoku2030@u.northwestern.edu>
To:        Mark Johnston <markj@freebsd.org>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Kernel panic when using pmap_extract_and_hold() to check physical-to-virtual address mapping
Message-ID:  <CAD2_vGrEWrM=hRJQUG8xeYhfBtLvvgKLtUrJ3moBag6hPi=xgw@mail.gmail.com>
In-Reply-To: <aR4JUjIZxR1dPh-m@nuc>
References:  <CAD2_vGoBqWmt%2BLgtTDOsJO9T_a2PdqZHjusv6EQeCRUDExxm1Q@mail.gmail.com> <aR4JUjIZxR1dPh-m@nuc>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Thank you for your response.

It happens every time we run the scan. Also, we're not checking for these
flags. Our test process is a simple user space program that mmaps memory
and waits, so P_WEXIT shouldn't be set, but we're not explicitly filtering
for it.

It could be possible that I'm getting vmspace0. Maybe it's returning that,
but I haven't checked. Here's my full code <https://pastebin.com/7NnTFXtv>.
I'll run this again, so I can get the output from the crash.
--Friedrich




On Wed, Nov 19, 2025 at 12:15 PM Mark Johnston <markj@freebsd.org> wrote:

> On Wed, Nov 19, 2025 at 11:51:02AM -0600, Friedrich Doku wrote:
> > Hello,
> >
> > We want to see if a specific physical address is mapped into the virtual
> > address space of a user space process. We are trying to do this from the
> > kernel, but we are running into issues with trying to use pmap_extract,
> > specifically we get the following kernel panic:
> >
> > panic: mtx_lock() of spin mutex (invalid)
>
> Does it always happen, or just sometimes?
>
> > The pmap pointer comes from:
> >
> >    1. pfind(target_pid) - gets the process structure
>
> Is it possible that one of P_WEXIT or P_SYSTEM is set in the p_flag
> field of the process?
>
> >    2. p->p_vmspace - gets the vmspace from the process
>
> Is it possible that p->p_vmspace == &vmspace0?
>
> >    3. vmspace_pmap(p->p_vmspace) - extracts the pmap from vmspace
> >
> > Then I'm iterating through vm_map entries with VM_MAP_ENTRY_FOREACH() and
> > calling pmap_extract_and_hold(pmap, va, VM_PROT_READ) for each virtual
> > address.
>
> Unrelated to your question, but this seems very slow.  Each physical
> page carries a list of virtual mappings which refer to it, the "PV
> entry" list.  You could instead look up the page by physical address
> (PHYS_TO_VM_PAGE()) and then walk the PV entry list for the page to find
> its mappings.  This comes with a couple of caveats:
> - PV entries are implemented in machine dependent code, i.e., in the
>   pmap layer, so some of your code would need to live there too.
> - PV entries don't record all mappings, just those that are mapped into
>   user address spaces via so-called "managed" mappings.
>
> > The crash happens when calling pmap_extract_and_hold(). I suspect it's
> > trying to acquire pmap locks that conflict with something.
> >
> > I'm trying to find which virtual address maps to a given physical address
> > in a user space process. I'm doing this from a kernel module via sysctl
> > handler.
> >
> > Best,
> > Friedy
>

[-- Attachment #2 --]
<div dir="ltr">Thank you for your response. <p>It happens every time we run the scan. Also, we&#39;re not checking for these flags. Our test process is a simple user space program that mmaps memory and waits, so P_WEXIT shouldn&#39;t be set, but we&#39;re not explicitly filtering for it. </p><p>It could be possible that I&#39;m getting vmspace0. Maybe it&#39;s returning that, but I haven&#39;t checked. Here&#39;s my full <a href="https://pastebin.com/7NnTFXtv" target="_blank">code</a>. I&#39;ll run this again, so I can get the output from the crash. </p>--Friedrich<p><br></p><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Nov 19, 2025 at 12:15 PM Mark Johnston &lt;<a href="mailto:markj@freebsd.org" target="_blank">markj@freebsd.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Nov 19, 2025 at 11:51:02AM -0600, Friedrich Doku wrote:<br>
&gt; Hello,<br>
&gt; <br>
&gt; We want to see if a specific physical address is mapped into the virtual<br>
&gt; address space of a user space process. We are trying to do this from the<br>
&gt; kernel, but we are running into issues with trying to use pmap_extract,<br>
&gt; specifically we get the following kernel panic:<br>
&gt; <br>
&gt; panic: mtx_lock() of spin mutex (invalid)<br>
<br>
Does it always happen, or just sometimes?<br>
<br>
&gt; The pmap pointer comes from:<br>
&gt; <br>
&gt;    1. pfind(target_pid) - gets the process structure<br>
<br>
Is it possible that one of P_WEXIT or P_SYSTEM is set in the p_flag<br>
field of the process?<br>
<br>
&gt;    2. p-&gt;p_vmspace - gets the vmspace from the process<br>
<br>
Is it possible that p-&gt;p_vmspace == &amp;vmspace0?<br>
<br>
&gt;    3. vmspace_pmap(p-&gt;p_vmspace) - extracts the pmap from vmspace<br>
&gt; <br>
&gt; Then I&#39;m iterating through vm_map entries with VM_MAP_ENTRY_FOREACH() and<br>
&gt; calling pmap_extract_and_hold(pmap, va, VM_PROT_READ) for each virtual<br>
&gt; address.<br>
<br>
Unrelated to your question, but this seems very slow.  Each physical<br>
page carries a list of virtual mappings which refer to it, the &quot;PV<br>
entry&quot; list.  You could instead look up the page by physical address<br>
(PHYS_TO_VM_PAGE()) and then walk the PV entry list for the page to find<br>
its mappings.  This comes with a couple of caveats:<br>
- PV entries are implemented in machine dependent code, i.e., in the<br>
  pmap layer, so some of your code would need to live there too.<br>
- PV entries don&#39;t record all mappings, just those that are mapped into<br>
  user address spaces via so-called &quot;managed&quot; mappings.<br>
<br>
&gt; The crash happens when calling pmap_extract_and_hold(). I suspect it&#39;s<br>
&gt; trying to acquire pmap locks that conflict with something.<br>
&gt; <br>
&gt; I&#39;m trying to find which virtual address maps to a given physical address<br>
&gt; in a user space process. I&#39;m doing this from a kernel module via sysctl<br>
&gt; handler.<br>
&gt; <br>
&gt; Best,<br>
&gt; Friedy<br>
</blockquote></div>

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAD2_vGrEWrM=hRJQUG8xeYhfBtLvvgKLtUrJ3moBag6hPi=xgw>