User: Password:
|
|
Subscribe / Log in / New account

Files with negative offsets

Files with negative offsets

Posted Jun 3, 2005 12:23 UTC (Fri) by farnz (subscriber, #17727)
In reply to: Files with negative offsets by giraffedata
Parent article: Files with negative offsets

The pain here is that AMD64 defines a 64-bit virtual address space; Opteron and Athlon64 only have a 48-bit virtual address space (40-bits physical), and define their own mappings from 48-bits to 64-bits. The choice is therefore to break the offset semantics and keep to AMD's documentation, or to define a new mapping for 48-bit to 63-bit, and have to rework it for a later processor with a 64-bit virtual address space.


(Log in to post comments)

Files with negative offsets

Posted Jun 3, 2005 15:09 UTC (Fri) by giraffedata (subscriber, #1954) [Link]

The choice is therefore to break the offset semantics and keep to AMD's documentation, or to define a new mapping for 48-bit to 63-bit, and have to rework it for a later processor with a 64-bit virtual address space.

I think those aren't the only options. For a 64 bit signed address space, I'd probably go with two files -- /dev/kmem where offset = address and /dev/kmem_minus where offset = -address .

Note that the negative offset solution Linus chose is not compatible with the full architectural specification either, because it doesn't work for addresses -1 - -4095, and not only the architecture but actual existing CPUs have such addresses.

(Reminder: -1 - -4095 don't work because in the loff_t type, those are error codes. I'm told it's not an immediate issue because Linux doesn't use those addresses).

gnikniht drawkcab

Posted Jun 7, 2005 7:20 UTC (Tue) by xoddam (subscriber, #2322) [Link]

> /dev/kmem_minus where offset = -address .

Now that's a bit silly. You'd have to *reverse* the contents of the
memory in the device driver when reading and writing!

offset = -address silly

Posted Jun 7, 2005 17:09 UTC (Tue) by giraffedata (subscriber, #1954) [Link]

Well, OK. Then: /dev/kmem_upper, where offset = 2^63 + address .

Files with negative offsets

Posted Jun 7, 2005 7:31 UTC (Tue) by farnz (subscriber, #17727) [Link]

Which CPUs currently have a 64-bit virtual address space? To the best of my knowledge, all AMD64 CPUs to date have a 48-bit virtual address space.

Two files is dangerous in terms of future compatibility, as AMD64 sign-extends addresses; thus, at the moment, I can read from 0xffffxxxxxxxx, where x is any hex digit, and get kernel addresses. In future, this becomes a userspace address (when the virtual space is extended to 49 or more bits), and my code suddenly breaks on me.

Linus's current solution works fine for as long as AMD64 processors have (or use) no more than 52-bits of virtual address space. I think the only long terms solution is to switch to 128-bit offset types, but that's going to be painful.

Files with negative offsets

Posted Jun 7, 2005 17:31 UTC (Tue) by giraffedata (subscriber, #1954) [Link]

Which CPUs currently have a 64-bit virtual address space?

No one said any CPU currently has a 64-bit virtual address space.

I did say current AMD64 CPUs have addresses -1 - -4095. All of them do.

The reason this Linux architectural gap doesn't matter for the /dev/kmem case is that Linux chooses not to use the address range -1 - -2^20. (I'm not sure why -- I just looked up a memory map just now to verify what I was told about Linus' solution working in spite of the -1 -4095 hole is true).

Two files is dangerous in terms of future compatibility, as AMD64 sign-extends addresses; thus, at the moment, I can read from 0xffffxxxxxxxx, where x is any hex digit, and get kernel addresses. In future, this becomes a userspace address (when the virtual space is extended to 49 or more bits), and my code suddenly breaks on me.

It's the other way around. The sign extension is what makes it work the same regardless of the virtual address space size. (In fact, it's evident to me that that's the whole point behind AMD64's negative address weirdness/innovation). The 48 bit address 0xffff fffffff0 is the address -16, which is identical to the 52 bit address 0xfffff fffffff0 or the 64 bit address 0xffffffff fffffff0. When you read address -16, you will never be reading user space.

In your C program, you should be using a pointer data type, which is 64 bits encoded in two's complement pure binary, which means that even today, your pointer is encoded with the 64 bits 0xffffffff fffffff0. Nothing would change.

I don't see 128 bit file offsets ever happening. /dev/kmem isn't what the POSIX file interface is for; what it is for won't need 128 bit offsets enough to justify the cost of the change.


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds