mmu: fix RCU page table walking

hw_ptep holds a pointer to a pt_element in rcu_ptr object, but this
is not the pointer that is protected by RCU, hw_ptep object are always
live on a stack and never accessed from more than one thread. The one
that is protected by RCU and can be changed concurrently resides in page
table itself. Fix that by making a pointer to point to atomic type and
use correct memory order during various accesses.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
mmu: make hw_ptep class to be a template parametrized on pte level

Utilize c++ type system to make it harder to pass wrong level ptes to
functions that expect certain pte level. Also, since now each hw_pte
level is different type, we can implement accessors differently for
each level. That allows us to use RCU accessors only for levels which
point to pages that can bee rcu freed, namely, level 1 and 2.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
mmu: remove size parameter from page ops class and file map/unmap functions

Now, when page level is encoded into hw_ptep, size parameter is no
longer needed since size can be deduced from pte itself.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
mmu: consolidate (small|huge)_page mapper operations

Now, when page level is encoded into hw_ptep, no need to have separate
handlers for small and large leaf pages. Most of them are nearly
identical anyways.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>