david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[librm] Support userptr_t in 64-bit builds

In a 64-bit build, the entirety of the 32-bit address space is
identity-mapped and so any valid physical address may immediately be
used as a virtual address.  Conversely, a virtual address that is
already within the 32-bit address space may immediately be used as a
physical address.

A valid virtual address that lies outside the 32-bit address space
must be an address within .textdata, and so can be converted to a
physical address by adding virt_offset.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2016-02-21 11:37:37 +00:00
parent b6ebafe1bb
commit 4c1f2486e6
1 changed files with 23 additions and 1 deletions

View File

@ -89,6 +89,15 @@ extern const unsigned long virt_offset;
*/
static inline __always_inline userptr_t
UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
/* In a 64-bit build, any valid physical address is directly
* usable as a virtual address, since the low 4GB is
* identity-mapped.
*/
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
return phys_addr;
/* In a 32-bit build, subtract virt_offset */
return ( phys_addr - virt_offset );
}
@ -101,7 +110,20 @@ UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
*/
static inline __always_inline unsigned long
UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) {
return ( userptr + offset + virt_offset );
unsigned long addr = ( userptr + offset );
/* In a 64-bit build, any virtual address in the low 4GB is
* directly usable as a physical address, since the low 4GB is
* identity-mapped.
*/
if ( ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) &&
( addr <= 0xffffffffUL ) )
return addr;
/* In a 32-bit build or in a 64-bit build with a virtual
* address above 4GB: add virt_offset
*/
return ( addr + virt_offset );
}
static inline __always_inline userptr_t