Writing to the physical memory in driver

In my driver I do the following operation for reading Physical Memory and it works fine: ULONGLONG data = 0;
ULONGLONG * VirtualAdd;
LARGE_INTEGER physicalAddress;
ULONGLONG InputData;
VirtualAdd = (ULONGLONG *)MmMapIoSpace(
physicalAddress,
memoryLength, //Bytes
MmNonCached
);
data = *(PULONG)VirtualAdd ; –> This works fine and I care for 32 bits only

For the write I get VirtualAdd as above then do
*(ULONGLONG *)VirtualAdd = InputData; –> I know no need to typecast just being paranoid :slight_smile:
I have checked InputData and it has correct value but when the above line is executed I zero the content. I am not writing.
What am I doing wrong?

If I were to do RtlCopyMemory() would it help?

Where did you get this physical address from? Unless you received it as a
device memory resource in EvtDevicePrepareHardware then what your doing is
fundamentally broken, you can’t call MmMapIoSpace on arbitrary physical
addresses.

What problem are you trying to solve?

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntdev…

In my driver I do the following operation for reading Physical Memory and it
works fine: ULONGLONG data = 0;
ULONGLONG * VirtualAdd;
LARGE_INTEGER physicalAddress;
ULONGLONG InputData;
VirtualAdd = (ULONGLONG *)MmMapIoSpace(
physicalAddress,
memoryLength, //Bytes
MmNonCached
);
data = *(PULONG)VirtualAdd ; –> This works fine and I care for 32 bits only

For the write I get VirtualAdd as above then do
*(ULONGLONG *)VirtualAdd = InputData; –> I know no need to typecast just
being paranoid :slight_smile:
I have checked InputData and it has correct value but when the above line is
executed I zero the content. I am not writing.
What am I doing wrong?

I am just a developer and giving the correct physical address is the users responsibility. For my testing the hardware architect gave me a address and he gave me demo using some other tool that the physical address is writable and system does not crash. Using the other tool I can write 0xDeadBeef and using my tool I can read it. However I could not write back a new value. When I do that it just get zeroed. The other tool can write. So what am I missing? So pleased assume all the parameters are valid.

xxxxx@gmail.com wrote:

In my driver I do the following operation for reading Physical Memory and it works fine: ULONGLONG data = 0;
ULONGLONG * VirtualAdd;
LARGE_INTEGER physicalAddress;
ULONGLONG InputData;
VirtualAdd = (ULONGLONG *)MmMapIoSpace(
physicalAddress,
memoryLength, //Bytes
MmNonCached
);
data = *(PULONG)VirtualAdd ; –> This works fine and I care for 32 bits only

For the write I get VirtualAdd as above then do
*(ULONGLONG *)VirtualAdd = InputData; –> I know no need to typecast just being paranoid :slight_smile:

Adding additional unnecessary typecasts is the OPPOSITE of paranoid,
because without them at least the compiler can WARN you when you have a
problem. Every typecast should be a red flag warning.

I have checked InputData and it has correct value but when the above line is executed I zero the content. I am not writing.
What am I doing wrong?

OK, just let me review here. You are saying that, with the setup above,
this works:
data = *(PULONG)VirtualAdd;
but this does not:
*(ULONGLONG*)VirtualAdd = InputData;
Is that right? How do you know? Are you reading the value back again
later? Does your hardware handle 64-bit write cycles? That’s what your
second line is doing. Does it work if you use the correct method:
WRITE_REGISTER_ULONG64(VirtualAdd, InputData);


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Are you trying to read/write a device register? Does your device supports writing 8 bytes from a register at once?

Sorry, wrong answer…We’ve been here many, many times on this list: “map
arbitrary physical pages” is not supported on Windows. See a lengthy
discussion (with links to other discussions) here:

http://www.osronline.com/showthread.cfm?link=179688

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntdev…

I am just a developer and giving the correct physical address is the users
responsibility. For my testing the hardware architect gave me a address and
he gave me demo using some other tool that the physical address is writable
and system does not crash. Using the other tool I can write 0xDeadBeef and
using my tool I can read it. However I could not write back a new value.
When I do that it just get zeroed. The other tool can write. So what am I
missing? So pleased assume all the parameters are valid.

Scott, I think the typecast might be issue, you are right. I agree typecasts are Red Flag will remember it for the future. Let me fix the code and try it out. I will get back to the forum in 30 min.

On Thu, Feb 18, 2016 at 11:08 AM, wrote:

> MmMapIoSpace

returns a PVOID - why are you coercing that to a ULONGLONG * and then
forcing VirtualAdd back to a PULONG? Makes no sense. If you wish to read
32bits from some address in memory, memoryLength ought to be “sizeof
ULONG”, VirtualAddr ought to be a PULONG and the only cast you need is
VirtualAdd = (PULONG) MmMapIoSpace.

Mark Roddy

Sorry for the delay. Thanks to Tim and Mark I cleaned up my code and it worked like a charm. The cleaned up code looks like this:
PVOID PVirtualAdd;
PVirtualAdd = MmMapIoSpace(
physicalAddress,
memoryLength, //Bytes
MmCached
);

*(ULONGLONG *)PVirtualAdd = PPhysMemInData->InputData;

Thanks

> VirtualAdd = (ULONGLONG *)MmMapIoSpace(

physicalAddress,
memoryLength, //Bytes
MmNonCached

Conflicting caching attributes for the same physical page will crash the OS.

Why are you interested in physical memory? the only valid use for it is a) to write the MM internals, but MM is already written by MS b) for DMA.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

That was the old code and I have fixed even the new code. Please check this URL:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn939699(v=vs.85).aspx
The heading says MmMapIoSpaceEx() but the actual call is still MmMapIoSpace(). What does MSFT mean by that naming convention? So I finally ended up using
PVOID PVirtualAdd;
PVirtualAdd = MmMapIoSpace(
physicalAddress,
memoryLength, //Bytes
PAGE_READWRITE | PAGE_NOCACHE
);

Things are working fine and this is the only call I make ignore all old calls.
I work for a company where we need to validate hardware I am just a tool developer.

xxxxx@gmail.com wrote:

That was the old code and I have fixed even the new code. Please check this URL:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn939699(v=vs.85).aspx
The heading says MmMapIoSpaceEx() but the actual call is still MmMapIoSpace(). What does MSFT mean by that naming convention?

It’s a simple documentation bug. The declaration in the example should
be MmMapIoSpaceEx. The function signature is the same.

I filed a comment about it.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

People did with the portio.sys driver hack, that enabled port I/O for a
given process. I’ve run into a number of companies lately who are finally
trying to go to 64-bit and realizing they need an approach to replace
portio.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Friday, February 19, 2016 4:56 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Writing to the physical memory in driver

xxxxx@gmail.com wrote:

That was the old code and I have fixed even the new code. Please check
this URL:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn939699(v=v
s.85).aspx The heading says MmMapIoSpaceEx() but the actual call is
still MmMapIoSpace(). What does MSFT mean by that naming convention?

It’s a simple documentation bug. The declaration in the example should be
MmMapIoSpaceEx. The function signature is the same.

I filed a comment about it.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

> Conflicting caching attributes for the same physical page will crash the OS.

Actually, IIRC, the only thing that you may get in case of such a conflict is the most restrictive caching policy being applied to a page, at least in case of MTTR/PTE attributes conflict. In any case, this is hardware-related thing - the OS software is not supposed to know about it, so that no exception will be generated by the CPU. Certainly, the OS may check the internal data structures and bluescreen upon the wrong request, but, IIRC, no such checks are made in case of MmMapIoSpace() call. More on it below…

Why are you interested in physical memory? the only valid use for it is a) to write the MM >internals, but MM is already written by MS b) for DMA.

IIRC, unlikeMmMapLockedPagesSpecifyCache(),MmMapIoSpace() modifies the target PTE directly without any other MM-related actions(). I think the only valid use of this function is to map memory-mapped device registers - IIRC, you are not supposed to deal with “regular” RAM this way. Although such mapping will be successful you may subseqently get some “interesting” results…

Anton Bassov