Search code examples
xv6virtual-address-space

Why does MAXVA in xv6 source code differ from the value in the xv6 textbook?


Why is the MAXVA value defined differently in the xv6 textbook of MIT 6s081 and the xv6 source code? The textbook states that the maximum address is 2^38 - 1 = 0x3fffffffff, while the source code defines MAXVA as (1L << (9 + 9 + 9 + 12 - 1)), which seems to be missing the -1. Can anyone explain the discrepancy and which one is correct?

The following screenshot is from xv6.pdf describing MAXVA, look at the yellow highlighted sentence: enter image description here

The following code snippet is from (kernel/kernel/riscv.h:348):

// one beyond the highest possible virtual address.
// MAXVA is actually one bit less than the max allowed by
// Sv39, to avoid having to sign-extend virtual addresses
// that have the high bit set.
#define MAXVA (1L << (9 + 9 + 9 + 12 - 1))

Solution

  • The last address available is 2^38-1

    The goal of MAXVA is that no address points to 2^38 or more.

    That's how MAXVA is used:

    We can check that in vm.h: Note that the address is compared to MAXVA with "greater on equal", not just "greater than".

    grep MAXVA -n vm.c -A 1
    88:  if(va >= MAXVA)
    89-    panic("walk");
    --
    114:  if(va >= MAXVA)
    115-    return 0;
    
    

    It's also explained in risc.h, the discrepancy you see is explained at lines 360, 361:

       359  // one beyond the highest possible virtual address.
       360  // MAXVA is actually one bit less than the max allowed by
       361  // Sv39, to avoid having to sign-extend virtual addresses
       362  // that have the high bit set.
       363  #define MAXVA (1L << (9 + 9 + 9 + 12 - 1))