xen/arm: p2m: Prevent deadlock when using memaccess
authorJulien Grall <julien.grall@arm.com>
Mon, 12 Mar 2018 15:34:52 +0000 (15:34 +0000)
committerStefano Stabellini <sstabellini@kernel.org>
Fri, 16 Mar 2018 20:58:28 +0000 (13:58 -0700)
commit0012ae8afb4a6e76f2847119f2c6850fbf41d9b7
tree295129ec38cf022b984c3abf32eddb7179919c88
parent6b270fae7ad462687550a875f714bff18d764416
xen/arm: p2m: Prevent deadlock when using memaccess

Commit 7d623b358a4 "arm/mem_access: Add long-descriptor based gpt"
assumed the read-write lock can be taken recursively. However, this
assumption is wrong and will lead to deadlock when the lock is
contended.

The read lock is taken recursively in the following case:
    1) get_page_from_gva
        => Take the read lock (first read lock)
        => Call p2m_mem_access_check_and_get_page on failure when
        memaccess is enabled
    2) p2m_mem_access_check_and_get_page
        => If hardware translation failed fallback to software lookup
        => Call guest_walk_tables
    3) guest_walk_tables
        => Will use access_guest_memory_by_ipa to access stage-1 page-table
    4) access_guest_memory_by_ipa
        => Because Arm does not have hardware instruction to only do
        stage-2 page-table, this is done in software.
        => Take the read lock (second read lock)

To avoid the nested lock, rework the locking in get_page_from_gva and
p2m_mem_access_check_and_get_page. The latter will now be called without
the p2m lock. The new locking in p2m_mem_accces_check_and_get_page will
not cover the translation of the VA to an IPA.

This is fine because we can't promise that the stage-1 page-table have
changed behind our back (they are under guest control). Modification in
the stage-2 page-table can now happen, but I can't issue any potential
issue here except with the break-before-make sequence used when updating
page-table. gva_to_ipa may fail if the sequence is executed at the same
on another CPU. In that case we would fallback in the software lookup
path.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Sergej Proskurin <proskurin@sec.in.tum.de>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/mem_access.c
xen/arch/arm/p2m.c
xen/include/asm-arm/p2m.h