7

From $ cat /proc/cpuinfo | grep address:

address sizes   : 39 bits physical, 48 bits virtual
address sizes   : 39 bits physical, 48 bits virtual

So, from my calculations pointer size is 64bits. 48bits are used to calculate physical address, and there are 16bits unused.

Can these free 16 bits be used safely?

If yes, then which are they? And how can they be used? Do I always have to bitmask the address, or something else?

Disclaimer: I'm designing low level conventions for programming language that I am gonna make. I need to pass an extra tiny information with some pointers and I would like to squeeze it into pointer if possible.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
kravemir
  • 10,636
  • 17
  • 64
  • 111

2 Answers2

12

In current architectures, the least-significant 48 bits of pointers are used by the CPU, leaving you the 16 most-significant bits to use as you wish. All you have to do is mask them off before you dereference a pointer and you will be fine.

In every OS I'm familiar with, bit 47 is 0 for user mode, so any user mode pointer will have the most-significant 17 bits be 0. This means a simple bit mask operation will turn your custom data into a pointer. If your pointers will be 8-byte aligned, you have an additional 3 low bits that you can use, giving you 20 free bits to do with as you please.

If you don't know whether your pointers will have their high bit set, you can store the pointer in the most-significant bits and do an arithmetic right shift to turn the custom value into a canonical pointer.

In other words, it is absolutely safe to use the otherwise-unused bits in pointer. There are just two rules you need to follow:

  1. Never use more bits than allowed. If the OS says 48 bits virtual, that means you can only use the high 16 bits. If some day a new CPU makes it say 50 bits virtual, you would only have 14 bits.

  2. Always produce a canonical pointer when dereferencing. That means the highest 16 bits must all be identical to the 17th bit. If you have 50 bits virtual, you have to make sure the highest 14 bits are identical to the 15th highest bit.

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • So, you're saying that these bits are safe to be used for custom data? :) – kravemir Jul 21 '15 at 08:30
  • A CPU just takes the instruction and executes it, so where will you masking and/or extracting? Also as I already mentioned this doesn't sound like a smart design, because OSs might be using these in the future, same with hardware. So eventually it will break. – m0skit0 Jul 21 '15 at 11:23
  • @Miro: I just edited the post to say that it is safe, so long as you follow the rules. – Gabe Jul 21 '15 at 16:05
  • 2
    PML5 allows 57-bit virtual addresses (an extra level of page tables). Ice Lake CPUs have it, I think. So aim to use the high 8 bits (if you want to assume user-space addresses have the highest significant bit zeroed), else high 7. If you only ever mess with the high 7 or 8 bits, redoing sign- or zero-extension respectively will work on 48-bit systems. – Peter Cordes Nov 24 '20 at 05:33
-4

Architecture supports 64-bit addressing, but current CPUs do not. You can only use 48 bits for addressing, so no, you can't use those 16 bits. Of course we're talking about physical addresses here. For virtual addresses you can indeed use 64-bit addressing.

If yes, then which are they? And how can they be used? Do I always have to bitmask the address, or something else?

They're the most significant ones. I don't know why you need to bitmask anything. Just don't use those bits.

Related question

Community
  • 1
  • 1
m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • 1
    I know that these bits ain't used for address resolution. I want them use for custom data :) – kravemir Jul 20 '15 at 17:52
  • 1
    As long as you mask off the custom bits before dereferencing the pointer, you can use them for whatever you wish. Just make sure you don't use more bits than are available and that your pointers are always canonical. – Gabe Jul 21 '15 at 06:42