]> xenbits.xensource.com Git - xen.git/commit
xen/arm: p2m: Introduce p2m_set_entry and __p2m_set_entry
authorJulien Grall <julien.grall@arm.com>
Thu, 15 Sep 2016 11:28:33 +0000 (12:28 +0100)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 28 Sep 2016 01:14:09 +0000 (18:14 -0700)
commit2ef3e36ec796a16c8839355c23eb119e72dc27fb
tree959a7833312ef5b8b5b4f3a572716d9a323e8344
parenta48a40e92f470cb8e41dd89b3a2b61e8d7c178e4
xen/arm: p2m: Introduce p2m_set_entry and __p2m_set_entry

The ARM architecture mandates to use of a break-before-make sequence
when changing translation entries if the page table is shared between
multiple CPUs whenever a valid entry is replaced by another valid entry
(see D4.7.1 in ARM DDI 0487A.j for more details).

The break-before-make sequence can be divided in the following steps:
    1) Invalidate the old entry in the page table
    2) Issue a TLB invalidation instruction for the address associated
    to this entry
    3) Write the new entry

The current P2M code implemented in apply_one_level does not respect
this sequence and may result to break coherency on some processors.

Adapting the current implementation to use the break-before-make
sequence would imply some code duplication and more TLBs invalidation
than necessary. For instance, if we are replacing a 4KB page and the
current mapping in the P2M is using a 1GB superpage, the following steps
will happen:
    1) Shatter the 1GB superpage into a series of 2MB superpages
    2) Shatter the 2MB superpage into a series of 4KB pages
    3) Replace the 4KB page

As the current implementation is shattering while descending and install
the mapping, Xen would need to issue 3 TLB invalidation instructions
which is clearly inefficient.

Furthermore, all the operations which modify the page table are using
the same skeleton. It is more complicated to maintain different code paths
than having a generic function that set an entry and take care of the
break-before-make sequence.

The new implementation is based on the x86 EPT one which, I think,
fits quite well for the break-before-make sequence whilst keeping
the code simple.

The main function of the new implementation is __p2m_set_entry. It will
only work on mapping that are aligned to a block entry in the page table
(i.e 1GB, 2MB, 4KB when using a 4KB granularity).

Another function, p2m_set_entry, is provided to break down is region
into mapping that is aligned to a block entry or 4KB when memaccess is
enabled.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Tested-by: Tamas K Lengyel <tamas@tklengyel.com>
xen/arch/arm/p2m.c
xen/include/asm-arm/p2m.h
xen/include/asm-arm/page.h