PCI bus-relative (physical) addresses

> I am not aware that any such “database” actually exists.

but having worked in the low-level guts of several operating systems in my life, I never once
saw anything resembling the table you propose.

Of course it does exist - otherwise the OS of any description will be unable to track the info of pages
(for example, how many VAs a given physical pages maps to, discover what these addresses actually are and to what address spaces they belong, etc). What the OP asks is whether this list describes only actual RAM or just everything that can be accessed as memory. …

Anton Bassov

Anton,

Having attended talks on Windows memory subsystem internals multiple
times, the one constant is “there is no inverted page table”, i.e. the
is no physical to virtual database. There is the page frame database,
and IIRC that does have a reference count for a page, but that is as far
as it goes.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
news:xxxxx@ntdev:

> > I am not aware that any such “database” actually exists.
>
> …
>
> > but having worked in the low-level guts of several operating systems in my life, I never once
> > saw anything resembling the table you propose.
>
> Of course it does exist - otherwise the OS of any description will be unable to track the info of pages
> (for example, how many VAs a given physical pages maps to, discover what these addresses actually are and to what address spaces they belong, etc). What the OP asks is whether this list describes only actual RAM or just everything that can be accessed as memory. …
>
> Anton Bassov

Don,

Having attended talks on Windows memory subsystem internals multiple times, the one constant
is “there is no inverted page table”,

Indeed, historically this has been the case. However, IIRC, someone from MSFT was saying in this NG that they had finally implemented reverse mapping (i.e the feature that some other OSes have had for many years) in Windows 7…

i.e. the is no physical to virtual database.

Well, it does not really have to be a “database”, i.e. a list of all PTEs that point to a page, because it would be terribly inefficient approach (just imagine the length of such list for a page from, say, NTDLL’s executable section). Therefore, some more sophisticated solution is needed. For example, Linux provides its implementation of reverse mapping mechanism that is based upon priority search trees. This mechanism allows one to quickly locate everyone who maps a given page without actually maintaining a list of PTEs…

Anton Bassov.

The OP made an invalid assumption: that the mapping is 1:1. This is
simply not true. Using memory-mapped files, shared-segment DLLs, and
shared-segment executables, plus MmGetSystemAddressForMdlSafe (or whatever
wraps it in KMDF), any given page frame could have a nominally unbounded
set of virtual addresses. So a “virtual-to-physical” map, besides being
useless except as a snapshot which could be obsolete before it is
processed, tells you nothing interesting except if it is a snapshot in a
particular context (one process, for example). Only the locked pages are
interesting, and since this state is itself dynamic, except for the
nonpaged pool, the information is largely untrustworthy in an active
execution environment. When the virtual-to-physical mapping required for
DMA is performed, it essentially uses the PFNs of the specific MDL to
derive these addresses, and the PFNs are established by
MmProbeAndLockPages, so those pages are locked.

Which goes back to the original question, of why the OP thinks this
information might have value.
joe

Anton,

Having attended talks on Windows memory subsystem internals multiple
times, the one constant is “there is no inverted page table”, i.e. the
is no physical to virtual database. There is the page frame database,
and IIRC that does have a reference count for a page, but that is as far
as it goes.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
> news:xxxxx@ntdev:
>
>> > I am not aware that any such “database” actually exists.
>>
>> …
>>
>> > but having worked in the low-level guts of several operating systems
>> in my life, I never once
>> > saw anything resembling the table you propose.
>>
>> Of course it does exist - otherwise the OS of any description will be
>> unable to track the info of pages
>> (for example, how many VAs a given physical pages maps to, discover what
>> these addresses actually are and to what address spaces they belong,
>> etc). What the OP asks is whether this list describes only actual RAM or
>> just everything that can be accessed as memory. …
>>
>> Anton Bassov
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

> The OP made an invalid assumption: that the mapping is 1:1.

You still don’t understand the OP’s question…

He does not ask us about “virtual-to-physical” map, which, indeed, would be just totally useless. He asks about
the list that describes physical page frames (in Linux terms, the list of struct PAGE structures) - he wonders if
it lists memory-mapped device ranges as well…

Anton Bassov

Anton is correct !

I do not ask about “virtual-to-physical” translation (performed via PTE’s) but about Page Frame Number (PFN) database.

From Windows Internals book PFN database has entries for each physical page frame (normally 4KB each) containing some page frame informations and its state. If it is included either in a working set list (process or system) or a non-paged system pool page maps to it, then its status is Active/Valid.

My guess is this is quite general: PFN entries exist for RAM page frame as well device memory-mapped ranges. Furthermore I guess page frame entries for memory-mapped ranges are always in Active/Valid state (as well RAM page frames non-paged system pool maps to)

So in Anton’s laptop there will exist PFN entries also for last Gigabyte memory hole starting at C0000000 where device’s register are mapped to…

The PFN database only includes pages that are part of the physical
memory map. It doesn’t include device ranges or even pages that are in
RAM but not part of the physical memory map (e.g. PFN 0).

> Which tool can i use on Win XP system (32 bit) to check how system RAM page frames are mapped

in CPU-relative phy address space ?

System RAM is mapped directly to the CPU.

More so, PCI BARs are mapped directly to the CPU. So, the address in a BAR is a CPU’s physical address.

Mapping only exists in DMA scenarios, if you have IOMMU logic in your north bridge, which is rather rare now. In this scenario, the DMA addresses set by the device go through the hardware mapping before being used as the RAM physical addresses.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> Based on this physical space layout a question arise: has PFN database entries also for memory-

mapped physical ranges (e.g. memory-mapped PCI device’s registers addresses)

No, PFN database is only for real RAM.

Mapped device BARs (MmMapIoSpace) is not in the PFN database.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> Anyway IIRC when driver’s ISR code is running (in interrupt context) it shouldn’t access controlled

device’s registers

Wrong. It should at least access the device status register to determine whether the device is actually interrupting. Also, in the end, it should update the device state so it will stop asserting the INT line.

via VAs because it could incurr in a BSOD (page tables could be paget out)

They can, but not for the nonpaged kernel space, where the MmMapIoSpace’d BAR’s live.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> (for example, how many VAs a given physical pages maps

IIRC Windows does not track this.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>mapped ranges. Furthermore I guess page frame entries for memory-mapped ranges are always in

Active/Valid state (as well RAM page frames non-paged system pool maps to)

The whole of PFN database is nonpaged.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>It doesn’t include device ranges or even pages that are in RAM but not part of the physical memory map (e.g. PFN 0)

Using lkd (windbg) on my win xp 32-bit client laptop I can see:

lkd> !pfn 0
PFN 00000000 at address 81DA6000
flink 00000000 blink / share count 00000001 pteaddress C07FE848
reference count 0001 Cached color 0
restore pte 00000000 containing page 000741 Active

lkd> !pte C07FE848
VA ffd09000
PDE at C0603FF0 PTE at C07FE848
contains 0000000000741163 contains 0000000000000163
pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV

lkd> !pte ffd09000
VA ffd09000
PDE at C0603FF0 PTE at C07FE848
contains 0000000000741163 contains 0000000000000163
pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV

Now it seem to me PFN 0 exist in PFN database (IIUC PFN 0 is page frame starting at CPU-relative physical address 0x00000000)

Can you help me ?

s/i see pfn/ i see pfn 0/
s / statred/ started/
s / i am not if / i am not sure if/

On 4/23/12, raj_r wrote:
> in my laptop i see pfn as zeroed
>
> but there is an undocumented command !pfn 0 1 which would yield a very
> very long output
> and iirc it always statred with page 1 and not 0 for for me
>
> i am not if what lkd shows could be used as i think many of the values
> might be stale not current etc
>
>
> lkd> !pfn 0 1
>
> Page Flink Blk/Shr Ref V PTE Address SavedPTE Frame State
> 1 17702 1e6c0 0 e1661048 0 4c0 2dff7 Standby P
> 2 2e090 145c9 0 e3f109e8 0 460 2aec4 Standby P
> 3 1192 155c 0 e2c205e0 0 460 14aad Standby P
> 4 0 1 1 c0029899 5313200 80 ffedcb Active
> RW
> 5 54a 1 1 c0001a20 344000 80 2ba2f Active M
> 6 1e947 2efc5 0 e477bbf0 0 4c0 7b30 Standby P
>
>
>
>
> On 4/23/12, xxxxx@alice.it wrote:
>>>It doesn’t include device ranges or even pages that are in RAM but not
>>> part
>>> of the physical memory map (e.g. PFN 0)
>>
>> Using lkd (windbg) on my win xp 32-bit client laptop I can see:
>>
>> lkd> !pfn 0
>> PFN 00000000 at address 81DA6000
>> flink 00000000 blink / share count 00000001 pteaddress
>> C07FE848
>> reference count 0001 Cached color 0
>> restore pte 00000000 containing page 000741 Active
>>
>> lkd> !pte C07FE848
>> VA ffd09000
>> PDE at C0603FF0 PTE at C07FE848
>> contains 0000000000741163 contains 0000000000000163
>> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>>
>> lkd> !pte ffd09000
>> VA ffd09000
>> PDE at C0603FF0 PTE at C07FE848
>> contains 0000000000741163 contains 0000000000000163
>> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>>
>> Now it seem to me PFN 0 exist in PFN database (IIUC PFN 0 is page frame
>> starting at CPU-relative physical address 0x00000000)
>>
>> Can you help me ?
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>

Check nt!MiPfnBitMap to see the entry is valid.

On 4/22/2012 4:20 PM, xxxxx@alice.it wrote:

> It doesn’t include device ranges or even pages that are in RAM but not part of the physical memory map (e.g. PFN 0)

Using lkd (windbg) on my win xp 32-bit client laptop I can see:

lkd> !pfn 0
PFN 00000000 at address 81DA6000
flink 00000000 blink / share count 00000001 pteaddress C07FE848
reference count 0001 Cached color 0
restore pte 00000000 containing page 000741 Active

lkd> !pte C07FE848
VA ffd09000
PDE at C0603FF0 PTE at C07FE848
contains 0000000000741163 contains 0000000000000163
pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV

lkd> !pte ffd09000
VA ffd09000
PDE at C0603FF0 PTE at C07FE848
contains 0000000000741163 contains 0000000000000163
pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV

Now it seem to me PFN 0 exist in PFN database (IIUC PFN 0 is page frame starting at CPU-relative physical address 0x00000000)

Can you help me ?

in my laptop i see pfn as zeroed

but there is an undocumented command !pfn 0 1 which would yield a very
very long output
and iirc it always statred with page 1 and not 0 for for me

i am not if what lkd shows could be used as i think many of the values
might be stale not current etc

lkd> !pfn 0 1

Page Flink Blk/Shr Ref V PTE Address SavedPTE Frame State
1 17702 1e6c0 0 e1661048 0 4c0 2dff7 Standby P
2 2e090 145c9 0 e3f109e8 0 460 2aec4 Standby P
3 1192 155c 0 e2c205e0 0 460 14aad Standby P
4 0 1 1 c0029899 5313200 80 ffedcb Active RW
5 54a 1 1 c0001a20 344000 80 2ba2f Active M
6 1e947 2efc5 0 e477bbf0 0 4c0 7b30 Standby P

On 4/23/12, xxxxx@alice.it wrote:
>>It doesn’t include device ranges or even pages that are in RAM but not part
>> of the physical memory map (e.g. PFN 0)
>
> Using lkd (windbg) on my win xp 32-bit client laptop I can see:
>
> lkd> !pfn 0
> PFN 00000000 at address 81DA6000
> flink 00000000 blink / share count 00000001 pteaddress C07FE848
> reference count 0001 Cached color 0
> restore pte 00000000 containing page 000741 Active
>
> lkd> !pte C07FE848
> VA ffd09000
> PDE at C0603FF0 PTE at C07FE848
> contains 0000000000741163 contains 0000000000000163
> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>
> lkd> !pte ffd09000
> VA ffd09000
> PDE at C0603FF0 PTE at C07FE848
> contains 0000000000741163 contains 0000000000000163
> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>
> Now it seem to me PFN 0 exist in PFN database (IIUC PFN 0 is page frame
> starting at CPU-relative physical address 0x00000000)
>
> Can you help me ?
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

here is an output from my laptop
lkd> .shell -ci “!address” grep -A 2 -B 2 -i “pfn”

819a6000 - 006f0000
Usage KernelSpaceUsagePFNDatabase

82096000 - 04d6a000
.shell: Process exited
lkd> dd /c 7 819a6000
819a6000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
819a601c 00017702 e1661048 0001e6c0 00001208 000004c0 861fa4e8 0002dff7
819a6038 0002e090 e3f109e8 000145c9 00001208 00000460 86bc2058 0002aec4
819a6054 00001192 e2c205e0 0000155c 00001208 00000460 8655b8c8 00014aad
819a6070 00000000 c0029899 00000001 00011606
lkd> !pfn 1
PFN 00000001 at address 819A601C
flink 00017702 blink / share count 0001E6C0 pteaddress E1661048
reference count 0000 Cached color 0
restore pte 861FA4E8000004C0 containing page 02DFF7
Standby P
Shared

lkd> dt -r nt!_MMPFN 819a601c
+0x000 u1 : __unnamed
+0x000 Flink : 0x17702
+0x000 WsIndex : 0x17702
+0x000 Event : 0x00017702 _KEVENT
+0x000 Header : _DISPATCHER_HEADER
+0x000 ReadStatus : 0n96002
+0x000 NextStackPfn : _SINGLE_LIST_ENTRY
+0x000 Next : 0x00017702 _SINGLE_LIST_ENTRY
+0x004 PteAddress : 0xe1661048 _MMPTE
+0x000 u : __unnamed
+0x000 Long : 0x18c6
+0x000 HighLow : _MMPTE_HIGHLOW
+0x000 Hard : _MMPTE_HARDWARE
+0x000 Flush : _HARDWARE_PTE
+0x000 Proto : _MMPTE_PROTOTYPE
+0x000 Soft : _MMPTE_SOFTWARE
+0x000 Trans : _MMPTE_TRANSITION
+0x000 Subsect : _MMPTE_SUBSECTION
+0x000 List : _MMPTE_LIST
+0x008 u2 : __unnamed
+0x000 Blink : 0x1e6c0
+0x000 ShareCount : 0x1e6c0
+0x00c u3 : __unnamed
+0x000 e1 : _MMPFNENTRY
+0x000 Modified : 0y0
+0x000 ReadInProgress : 0y0
+0x000 WriteInProgress : 0y0
+0x000 PrototypePte : 0y1
+0x000 PageColor : 0y000
+0x000 ParityError : 0y0
+0x000 PageLocation : 0y010
+0x000 RemovalRequested : 0y0
+0x000 CacheAttribute : 0y01
+0x000 Rom : 0y0
+0x000 LockCharged : 0y0
+0x000 DontUse : 0y0000000000000000 (0)
+0x000 e2 : __unnamed
+0x000 ShortFlags : 0x1208
+0x002 ReferenceCount : 0
+0x010 OriginalPte : _MMPTE
+0x000 u : __unnamed
+0x000 Long : 0x861fa4e8`000004c0
+0x000 HighLow : _MMPTE_HIGHLOW
+0x000 Hard : _MMPTE_HARDWARE
+0x000 Flush : _HARDWARE_PTE
+0x000 Proto : _MMPTE_PROTOTYPE
+0x000 Soft : _MMPTE_SOFTWARE
+0x000 Trans : _MMPTE_TRANSITION
+0x000 Subsect : _MMPTE_SUBSECTION
+0x000 List : _MMPTE_LIST
+0x018 u4 : __unnamed
+0x000 EntireFrame : 0x2dff7
+0x000 PteFrame : 0y00000000101101111111110111 (0x2dff7)
+0x000 InPageError : 0y0
+0x000 VerifierAllocation : 0y0
+0x000 AweAllocation : 0y0
+0x000 LockCharged : 0y0
+0x000 KernelStack : 0y0
+0x000 Reserved : 0y0

lkd> dt -r nt!_MMPFN 819a6000
+0x000 u1 : __unnamed
+0x000 Flink : 0
+0x000 WsIndex : 0
+0x000 Event : (null)
+0x000 ReadStatus : 0n0
+0x000 NextStackPfn : _SINGLE_LIST_ENTRY
+0x000 Next : (null)
+0x004 PteAddress : (null)
+0x008 u2 : __unnamed
+0x000 Blink : 0
+0x000 ShareCount : 0
+0x00c u3 : __unnamed
+0x000 e1 : _MMPFNENTRY
+0x000 Modified : 0y0
+0x000 ReadInProgress : 0y0
+0x000 WriteInProgress : 0y0
+0x000 PrototypePte : 0y0
+0x000 PageColor : 0y000

On 4/23/12, raj_r wrote:
> s/i see pfn/ i see pfn 0/
> s / statred/ started/
> s / i am not if / i am not sure if/
>
> On 4/23/12, raj_r wrote:
>> in my laptop i see pfn as zeroed
>>
>> but there is an undocumented command !pfn 0 1 which would yield a very
>> very long output
>> and iirc it always statred with page 1 and not 0 for for me
>>
>> i am not if what lkd shows could be used as i think many of the values
>> might be stale not current etc
>>
>>
>> lkd> !pfn 0 1
>>
>> Page Flink Blk/Shr Ref V PTE Address SavedPTE Frame State
>> 1 17702 1e6c0 0 e1661048 0 4c0 2dff7 Standby
>> P
>> 2 2e090 145c9 0 e3f109e8 0 460 2aec4 Standby
>> P
>> 3 1192 155c 0 e2c205e0 0 460 14aad Standby
>> P
>> 4 0 1 1 c0029899 5313200 80 ffedcb Active
>> RW
>> 5 54a 1 1 c0001a20 344000 80 2ba2f Active
>> M
>> 6 1e947 2efc5 0 e477bbf0 0 4c0 7b30 Standby
>> P
>>
>>
>>
>>
>> On 4/23/12, xxxxx@alice.it wrote:
>>>>It doesn’t include device ranges or even pages that are in RAM but not
>>>> part
>>>> of the physical memory map (e.g. PFN 0)
>>>
>>> Using lkd (windbg) on my win xp 32-bit client laptop I can see:
>>>
>>> lkd> !pfn 0
>>> PFN 00000000 at address 81DA6000
>>> flink 00000000 blink / share count 00000001 pteaddress
>>> C07FE848
>>> reference count 0001 Cached color 0
>>> restore pte 00000000 containing page 000741 Active
>>>
>>> lkd> !pte C07FE848
>>> VA ffd09000
>>> PDE at C0603FF0 PTE at C07FE848
>>> contains 0000000000741163 contains 0000000000000163
>>> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>>>
>>> lkd> !pte ffd09000
>>> VA ffd09000
>>> PDE at C0603FF0 PTE at C07FE848
>>> contains 0000000000741163 contains 0000000000000163
>>> pfn 741 -G-DA–KWEV pfn 0 -G-DA–KWEV
>>>
>>> Now it seem to me PFN 0 exist in PFN database (IIUC PFN 0 is page frame
>>> starting at CPU-relative physical address 0x00000000)
>>>
>>> Can you help me ?
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> For our schedule of WDF, WDM, debugging and other seminars visit:
>>> http://www.osr.com/seminars
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http://www.osronline.com/page.cfm?name=ListServer
>>>
>>
>

> here is an output from my laptop lkd> .shell -ci “!address” grep -A 2 -B 2 -i “pfn”

raj, .shell command on my XP laptop does not find “grep” utility…how can I solve it ?

Thanks

I’ll combine a couple of posts in one:

wrote in message…
>Of course it does exist - otherwise the OS of any description will be
>unable to track the info of pages
>(for example, how many VAs a given physical pages maps to, discover what
>these addresses actually
>are and to what address spaces they belong, etc).

Why do you assume that this information is required on Windows? Windows
needs to know that multiple addresses point to a single page, but it doesn’t
necessarily need to know which pages point to the physical page. The
former is dealt with through the Prototype PTE concept, the latter is only
addressed partially starting in Windows 7. Which brings me to the next
point:

wrote in message…
>Indeed, historically this has been the case. However, IIRC, someone from
>MSFT was saying in this
>NG that they had finally implemented reverse mapping (i.e the feature that
>some other OSes have
>had for many years) in Windows 7…

Can you find that conversation? AFAIK, that still doesn’t exist in Windows
7. If you can find that support somewhere I’m sure you’ll make lots of
people happy though.

There was some semi-related support added in Windows 7 to track mappings on
a per-control area basis. This allows support for a new API that invalidates
user mapped views when flushing/purging cached data from a file system, but
it’s a far cry from a complete reverse lookup table.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

On 4/23/12, xxxxx@alice.it wrote:
>> here is an output from my laptop lkd> .shell -ci “!address” grep -A 2 -B 2
>> -i “pfn”
>
> raj, .shell command on my XP laptop does not find “grep” utility…how can I
> solve it ?
>

a couple of ways

download install and add it to path so it is accessible

http://gnuwin32.sourceforge.net/packages/grep.htm

substitute FINDSTR an inbuilt utility instead of grep

remove the .shell command completely just issue !address and use
ctrl+f in windbg output window

open a logfile before starting windbg and use plain !address and later
parse the log

or you can try this windbg extension also
http://www.denismo.name/domdbg/WebPages/MainPage.htm