|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xen/arm: p2m: Don't use default access permission when shattering a superpage
On Fri, 29 Jul 2016, Julien Grall wrote:
> The following message flood the console when memaccess is enabled on
> various platforms:
>
> traps.c:2510:d1v0 HSR=0x9383004f pc=0xffff000008b7d4c4 gva=0xffff000008eeb8e0
> gpa=0x0000004903f8e0
>
> This is because a data abort from a guest was received due to a
> permission fault but memaccess thought there are no permission fault.
>
> On ARM, memaccess permissions are stored in a radix tree because there
> are not enough available bits in the p2m entry to store the access
> restriction. When memaccess is restricting the access (i.e any other
> access than p2m_access_rwx), the access will be added in the radix tree
> using the GFN as a key. This will be done for all 4KB pages.
>
> This means that memaccess has to shatter all the superpages in a given
> region to set the permission on a 4KB granularity. Currently, when a
> superpage is shattered, the new entries are using the value
> p2m->default_access which will restrict permission (because memaccess
> has been enabled). However the radix tree does not yet contain
> an entry for this GFN.
>
> If a guest VCPU is running at the same time and trying to access the
> modified region, it will result to a stage-2 permission fault. As
> the radix tree does not yet contain an entry for the GFN, memaccess will
> deduce that the fault was not valid and a data abort will be injecting
> to the guest (and crash it).
>
> Furthermore, the permission may be restricted outside of the requested
> region if it is only a subset of a 1GB/2MB superpage.
>
> The two issues can be fixed by re-using the permission of the superpage
> entry and override the necessary fields. This is not a problem because
> memaccess cannot work on superpage.
>
> Lastly, document the code which call mfn_to_p2m_entry when creating a
> the p2m entry for a table to explain that create the p2m entry to page table
> to explain that permission are ignored by the hardware (See D4.3.1 in ARM DDI
> 0487A.j). so the value of the parameter 'access' of mfn_to_p2m_entry does
> not matter.
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> ---
> This patch needs to be backported up to Xen 4.6 (first release
> which introduced memaccess on ARM). This may require few adjustement
> because the code has changed a bit.
>
> Without it, the guest will randomly crash because the permission has
> been overriden whilst shattering a superpage and before adding the access
> permission in the radix tree.
>
> Also I am wondering if it would be better to pass p2m_access_rwx
> to mfn_to_p2m_entry when creating a table entry. This would save
> a couple of instructions.
> ---
> xen/arch/arm/p2m.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 40a0b80..d60fbbf 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -434,7 +434,6 @@ static int p2m_create_table(struct p2m_domain *p2m,
> lpae_t *entry,
> p = __map_domain_page(page);
> if ( splitting )
> {
> - p2m_type_t t = entry->p2m.type;
> mfn_t mfn = _mfn(entry->p2m.base);
> int i;
>
> @@ -444,15 +443,20 @@ static int p2m_create_table(struct p2m_domain *p2m,
> lpae_t *entry,
> */
> for ( i=0 ; i < LPAE_ENTRIES; i++ )
> {
> - pte = mfn_to_p2m_entry(mfn_add(mfn, i << (level_shift -
> LPAE_SHIFT)),
> - t, p2m->default_access);
> + /*
> + * Use the content of the superpage entry and override
> + * the necessary fields. So the correct permissions are
> + * kept.
> + */
> + pte = *entry;
> + pte.p2m.base = mfn_x(mfn_add(mfn,
> + i << (level_shift - LPAE_SHIFT)));
>
> /*
> * First and second level super pages set p2m.table = 0, but
> * third level entries set table = 1.
> */
> - if ( level_shift - LPAE_SHIFT )
> - pte.p2m.table = 0;
> + pte.p2m.table = !(level_shift - LPAE_SHIFT);
>
> write_pte(&p[i], pte);
> }
> @@ -467,6 +471,10 @@ static int p2m_create_table(struct p2m_domain *p2m,
> lpae_t *entry,
>
> unmap_domain_page(p);
>
> + /*
> + * The access value does not matter because the hardware will ignore
> + * the permission fields for table entry.
> + */
> pte = mfn_to_p2m_entry(_mfn(page_to_mfn(page)), p2m_invalid,
> p2m->default_access);
>
> --
> 1.9.1
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |