|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2] x86/mm: Add mem access rights to NPT
On 22.08.2019 16:02, Alexandru Stefan ISAILA wrote:
> This patch adds access control for NPT mode.
>
> The access rights are stored in the NPT p2m table 56:53.
Why starting from bit 53? I can't seem to find any use of bit 52.
> The bits are free after clearing the IOMMU flags [1].
>
> Modify p2m_type_to_flags() to accept and interpret an access value,
> parallel to the ept code.
>
> Add a set_default_access() method to the p2m-pt and p2m-ept versions
> of the p2m rather than setting it directly, to deal with different
> default permitted access values.
I think this would better be a separate change.
> --- a/xen/arch/x86/mm/p2m-pt.c
> +++ b/xen/arch/x86/mm/p2m-pt.c
> @@ -63,10 +63,13 @@
> #define needs_recalc(level, ent) _needs_recalc(level##e_get_flags(ent))
> #define valid_recalc(level, ent) (!(level##e_get_flags(ent) &
> _PAGE_ACCESSED))
>
> +#define _PAGE_ACCESS_BITS (0x1e00) /* mem_access rights 16:13 */
I guess this is too disconnected from the two page.h headers where
the correlation between bit positions gets explained, so I guess
you want to extend the comment and either refer there, or replicate
some of it to make understandable why 16:13 matches 56:53.
I'm also concerned how easy it'll be for someone to find this
definition when wanting to use other of the available bits.
> @@ -104,8 +112,32 @@ static unsigned long p2m_type_to_flags(const struct
> p2m_domain *p2m,
> flags |= _PAGE_PWT;
> ASSERT(!level);
> }
> - return flags | P2M_BASE_FLAGS | _PAGE_PCD;
> + flags |= P2M_BASE_FLAGS | _PAGE_PCD;
> + break;
> }
> +
> + switch ( access )
> + {
> + case p2m_access_r:
> + flags |= _PAGE_NX_BIT;
> + flags &= ~_PAGE_RW;
> + break;
> + case p2m_access_rw:
> + flags |= _PAGE_NX_BIT;
> + break;
> + case p2m_access_rx:
> + case p2m_access_rx2rw:
> + flags &= ~(_PAGE_NX_BIT | _PAGE_RW);
> + break;
> + case p2m_access_x:
> + flags &= ~_PAGE_RW;
> + break;
I can't seem to be able to follow you here. In fact I don't see
how you would be able to express execute-only with NPT. If this
is really needed for some reason, then a justifying comment
should be added.
> @@ -152,6 +184,17 @@ p2m_free_entry(struct p2m_domain *p2m, l1_pgentry_t
> *p2m_entry, int page_order)
> p2m_free_ptp(p2m, l1e_get_page(*p2m_entry));
> }
>
> +static void p2m_set_access(intpte_t *entry, p2m_access_t access)
> +{
> + *entry |= put_pte_flags((get_pte_flags(*entry) & ~_PAGE_ACCESS_BITS) |
> + (MASK_INSR(access, _PAGE_ACCESS_BITS)));
> +}
> +
> +static p2m_access_t p2m_get_access(intpte_t entry)
> +{
> + return (p2m_access_t)(MASK_EXTR(get_pte_flags(entry),
> _PAGE_ACCESS_BITS));
Is the cast really needed here?
> @@ -226,6 +269,7 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
> {
> new_entry = l1e_from_pfn(pfn | (i << ((level - 1) *
> PAGETABLE_ORDER)),
> flags);
> + p2m_set_access(&new_entry.l1, p2m->default_access);
> rc = p2m->write_p2m_entry(p2m, gfn, l1_entry + i, new_entry,
> level);
> if ( rc )
> {
> @@ -237,6 +281,7 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
> unmap_domain_page(l1_entry);
>
> new_entry = l1e_from_mfn(mfn, P2M_BASE_FLAGS | _PAGE_RW);
> + p2m_set_access(&new_entry.l1, p2m->default_access);
> rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry,
> level + 1);
> if ( rc )
Is it really intended to insert the access bits also into non-leaf
entries (which may be what is being processed here)? (May also
apply further down.)
> @@ -474,6 +520,32 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa)
> return rc;
> }
>
> +static int p2m_pt_check_access(p2m_access_t p2ma)
> +{
> + switch ( p2ma )
> + {
> + case p2m_access_n:
> + case p2m_access_w:
> + case p2m_access_wx:
> + case p2m_access_n2rwx:
> + return -EINVAL;
I'm not convinced EINVAL is appropriate here - the argument isn't
invalid, it's just that there's no way to represent it.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |