[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] x86/ept: limit calls to memory_type_changed()


  • To: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 28 Sep 2022 10:01:26 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=omiiGGBA9Y0nyz+SvNAtNjvZxtSrppAg41tJmWHsaGQ=; b=GngGiJ4BbiukZFAigSBiO9koGYGIfAlWO+gHE6OUAhemaUhDLF3j/vLAW+3RaciFBteow7ai1CjVfSIuAaKJiQj/80S6KMVD9ygBB5ir4ySnpiX5TpA828sAqCQ3dGtzSNXc/TWJDpT8r1cyCedptOPLwPM9G8xzEVm8y8iAEqS1aRIlVntFmbBhPH7IsbyA7Ep5dmw6l0WjNzpxnsDpCB0BIBXVEynDprxs6ixxJrNKSdij6Mj8Cp6RyTs1P1LnR7UNwDeHkycVZmqHFPMmIfUrjvO6OJ2dke6vz9NI7E+Pl3fONUHr7RoGs5WbW27lSexApec5oazjW8fadBpwtg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=h0GEpvtgePt7+khs1D1IcmJB8+29dPegO+2B5Wq/+Ed0CMfSZprL37OpJMs59KHA3mgMfvZbd4GAt/bFJieL1LmRdGibR4vkT7C1YoFmpSefgJv7PXABVLdkpNY7bOGZ9AQdiqIxRwKCf1rwPrXCGW8uzxsAaVuE4ubNLnTyeflt4VjXD7Zir8PrySJLfqYdawdWi626538izSm+hZkTu7JOzV5NjrEWTwpjCERlcJvX4VRq825ZG1m/e01qt2ufGQgVSWMcUCnZx5Xl8TPGcZe4YcT+ChGQeySqpmvByhdZrXIWZZcrCNAusPYTY2McvtAnTZk+ICGwxW6SUvvoJA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Jun Nakajima <jun.nakajima@xxxxxxxxx>, Kevin Tian <kevin.tian@xxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Wed, 28 Sep 2022 08:01:48 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 27.09.2022 17:39, Roger Pau Monne wrote:
> memory_type_changed() is currently only implemented for Intel EPT, and
> results in the invalidation of EMT attributes on all the entries in
> the EPT page tables.  Such invalidation causes EPT_MISCONFIG vmexits
> when the guest tries to access any gfns for the first time, which
> results in the recalculation of the EMT for the accessed page.  The
> vmexit and the recalculations are expensive, and as such should be
> avoided when possible.
> 
> Remove the call to memory_type_changed() from
> XEN_DOMCTL_memory_mapping: there are no modifications of the
> iomem_caps ranges anymore that could alter the return of
> cache_flush_permitted() from that domctl.
> 
> Encapsulate calls to memory_type_changed() resulting from changes to
> the domain iomem_caps or ioport_caps ranges in the helpers themselves
> (io{ports,mem}_{permit,deny}_access()), and add a note in
> epte_get_entry_emt() to remind that changes to the logic there likely
> need to be propagaed to the IO capabilities helpers.
> 
> Note changes to the IO ports or memory ranges are not very common
> during guest runtime, but Citrix Hypervisor has an use case for them
> related to device passthrough.
> 
> Some Arm callers (implementations of the iomem_deny_access function
> pointer field in gic_hw_operations struct) pass a const domain pointer
> to iomem_deny_access(), which is questionable.  It works because
> the rangeset is allocated separately from the domain struct, but
> conceptually seems wrong to me, as passing a const pointer would imply
> no changes to the domain data, and denying iomem accesses does change
> the domain data.  Fix this by removing the const attribute from the
> affected functions and call chain.

Personally I think this adjustment would better be a separate, prereq
change.

> --- a/xen/include/xen/iocap.h
> +++ b/xen/include/xen/iocap.h
> @@ -7,13 +7,43 @@
>  #ifndef __XEN_IOCAP_H__
>  #define __XEN_IOCAP_H__
>  
> +#include <xen/sched.h>
>  #include <xen/rangeset.h>
>  #include <asm/iocap.h>
> +#include <asm/p2m.h>

That's heavy dependencies you're adding. I wonder if the functions
wouldn't better become out-of-line ones (but see also below).

> +static inline int iomem_permit_access(struct domain *d, unsigned long s,
> +                                      unsigned long e)
> +{
> +    bool flush = cache_flush_permitted(d);
> +    int ret = rangeset_add_range(d->iomem_caps, s, e);
> +
> +    if ( !ret && !is_iommu_enabled(d) && !flush )
> +        /*
> +         * Only flush if the range(s) are empty before this addition and
> +         * IOMMU is not enabled for the domain, otherwise it makes no
> +         * difference for effective cache attribute calculation purposes.
> +         */
> +        memory_type_changed(d);
> +
> +    return ret;
> +}
> +static inline int iomem_deny_access(struct domain *d, unsigned long s,
> +                                    unsigned long e)
> +{
> +    int ret = rangeset_remove_range(d->iomem_caps, s, e);
> +
> +    if ( !ret && !is_iommu_enabled(d) && !cache_flush_permitted(d) )
> +        /*
> +         * Only flush if the range(s) are empty after this removal and
> +         * IOMMU is not enabled for the domain, otherwise it makes no
> +         * difference for effective cache attribute calculation purposes.
> +         */
> +        memory_type_changed(d);
> +
> +    return ret;
> +}

I'm surprised Arm's memory_type_changed() is an empty out-of-line function.
This means the compiler can't eliminate this code (except when using LTO).
But then cache_flush_permitted() (resolving to rangeset_is_empty()) can't
be eliminated either, even if memory_type_changed() was. While gcc doc
doesn't explicitly say that it may help (the talk about repeated invocations
only), I wonder whether we shouldn't mark rangeset_is_empty() pure. In a
reduced example that does help (once memory_type_changed() is also an
inline function) with gcc12 - no call to rangeset_is_empty() remains.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.