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

Re: [PATCH 1/2] x86: correct is_pv_domain() when !CONFIG_PV


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Mon, 12 Apr 2021 11:34:31 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.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-SenderADCheck; bh=spCQjae4mmuQKnFFW4X5FnTPZuvVMl2ST4dGncrUvek=; b=ka/lgDoYUkbYDIKADoCgAFMoNhuKM0ccBDl0vRHVFgalGU/sfRIyEqBAGqlIqdYyTWDEaok28MRrmbaWcDpxEVXdNrQ3qfNIDTec96roSFENU17XNR0VqH4xrA8Hwk9Ps8qkPIANJP0t+CF+nll6mpi5ZgkWYl7Mf8Q3TZLXhzFgPakyXPDfmjo1J/Pt6/hhR+KSI8EBasu3oRGiEt4izHvc9eAUb+iidrlPj7fBUDFV2UaO4ja9Zcse6UktNfye20Ov4lcAsJvMVjsa5SOrEhYuSsHkrKf/5SSO6ZdSoQEWuKqzIFpltNjEjm4cYqSuSpsTghopq2HRn2Q1pHz1PA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=B8M1fbMutmMzftrc2oW/Nch8+IZ4+VdtxVko8lpONKu6y4GOrWCdN7NRciQnXgZJa45eVIz31xIeSH9lis/hTBByrR1HNFrTxko4Iwy09it1FDgRldS1bTPdNb5vNblQ5tphMjsBo/1CDGaC6DhLlqYcfk7gKDvV80V5FugAAaRpttU4vh4lSDZtmoVm/mHTwyku2QOUY2yQCilZEzRF3ypCuXjUObCmkLrEx3At9ZYJ9HAx6UV4ZyUwHmCtAvSSpzXoxp/JbQT3QScJ0ty51nYk2uqO3S1Wh3sa3PSiZwZVRIbRuv3gugOYdk5ned8toijA2WLinK0g/sZIVq6s/A==
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Mon, 12 Apr 2021 09:34:47 +0000
  • Ironport-hdrordr: A9a23:QW5UiKC1hrPPynTlHegctMeALOonbusQ8zAX/mhLY1h8btGYm8 eynP4SyB/zj3IrVGs9nM2bUZPufVr1zrQwxYUKJ7+tUE3duGWuJJx/9oeK+VHdMgXE3Kpm2a 9kGpISNPTZEUV6gcHm4AOxDtYnx529/Lq1gPrFpk0NcShBQchbnmBEIyycFVB7QxQDKJoiDZ yH5tdGoT3IQwVsUu2QAH4ZU+/f4+DRnJX9bhIcQzIh4g+CjTSngYSKbiSw9BEYTj9J3PMe4X HI+jaJnZmLntOa7lvn12HV54lLg9eJ8LV+LeGFl8R9EESPti+Gf4JkMofy2QwdgObq01oylc mJnhFIBbUO11r0XkWY5STgwBPh1jFG0Q6T9Xa9jWH4qcL0ABIWYvAx/L5xSRfS50o+sNwU6s sitAj4xvknfy/opyjz68PFUBtnjCOP0AIfuNUekmBFVs8mYKJRxLZvjX99KosKHy7x9ekcYY 9TJfzbjcwmFW+yXjTyu2lix8GURXIjHhuKaVhqgL3q7xFm2F9+1EcW38oZgzMp8488UYBN46 D+Pr1vj6wmdL5bUYtNQMM6BeenAG3ERhzBdEqUPFTcDakCf1bAsYT+7rkZ7PyjEaZ4g6caqd Dkahd1pGQyc0XhBYmlx5tQ6C3AR227QHDE1txez4IRgMy9eJPbdQm4DHw+mcqppPsSRufBXe yoBZ5QC/j/aUPzBIdy2RHkUZU6EwhebOQl/vIAH36eqMPCLYPn8sbBduzIGbbrGTE4HkzlBH 8uWyXyOdVg4kinVmSQummSZ1rdPmjEub5gGqnT+OYejKIXMJdXjwQTgVOlouGHQAcy95AeTQ 9bGvfKg6m7rW658SLj9GNyICdQCU5T/fHFW3NOrgkaDlPsfd84ypGiUFEX+EHCCg50TsvQHg IajU9w47iLI5uZwj1nLN67LGSAjT82qGiRR5kR3o2PjP2VNK8QP9IDYuhcBA/LHxt6lUJBs2 FYcjIJQUfZC3fJkqWqjJsdAcnFbNliiAKXIcpZwEiv9nm0lIUKfD82TjSuWcmYjUIFXDxPnG B89KcZnf69gzq1EHA+h+45KVVIT2ySDNt9fUO4TbQRvoquVBB7TG+MizDfrx0oYGLl+38fgX HbITSOdevGBUdcvX5kwr/nmWkEBVm1TgZVUDRXoId9HWPJtjJI3eiHarGa/kGRZlEBq9ttew 3tUH83GEdD1tq33BmalHK+Dn0g3IwpJfGYJq8kaavv1nSkL5ComakKE+RPxotsMMnjv4YwIK SiUj7QCAm9J/Ii2gSTqHpgBTJ9r2M8l+j0nDLi92q10RcEcIzvCWUjY4teBd6S72LpHanVlL p4iM84puu2PCHabMWcxaTecj5ELVfyrAeNPpUVgKERmZh3kr15W6T/e3/v8lps2R0lNsf6lE 8EWs1Akfj8E74qW/ZXQj5T+1oiqc+GI0QquDHnG+NWRyBZs1bre/eyp4fSobUhAke9tBL9FF mW/Spa5erEVUK4pMknIpN1BWRdc04n7nt+uMuEao3LEQ2vHtsztmaSAzuYcLVHTrKCFqhVhh Fm48uQl+vSUybjwgjfsX9aJa1JmlzXDP+aMUapGeRS9ca9NknJqqy24NSrhDOycACFUS0j9M R4XH1VSN9ChDkkhJA21Sb3apWfmDNbr3JupRd9llDs3YC65nz8Bk8uC3yBvqlr
  • Ironport-sdr: acSbpTBlzjf71CRwvitfCn8vhE7q1RDV/aOisLZvUqdSD1lZE7D9/YCzr2yVzXONaNL8lyd9TI E7RdUPCeQdB3EGUSgyv6QzASoq12Z6mBmSHuR/6uIFFXi5GwNdvInRIF6o3VoRBLtHP78Tu1nH aP8WSm9DJdeewN2Cmv9O1QP81T6bSGRsPXosII4jmtW8fG0vqXhyv94eJy6E8G2JDcitT8QevN lLlX/FjVi2ra0Bv27J5mbcN0TRxUHQOFRA/onfX/iuMCtLoqrjiAfBaX7vc4LpIhWBib0sgK8u tjs=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Fri, Nov 27, 2020 at 05:54:57PM +0100, Jan Beulich wrote:
> On x86, idle and other system domains are implicitly PV. While I
> couldn't spot any cases where this is actively a problem, some cases
> required quite close inspection to be certain there couldn't e.g. be
> some ASSERT_UNREACHABLE() that would trigger in this case. Let's be on
> the safe side and make sure these always have is_pv_domain() returning
> true.
> 
> For the build to still work, this requires a few adjustments elsewhere.
> In particular is_pv_64bit_domain() now gains a CONFIG_PV dependency,
> which means that is_pv_32bit_domain() || is_pv_64bit_domain() is no
> longer guaranteed to be the same as is_pv_domain().
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> 
> --- a/xen/arch/x86/dom0_build.c
> +++ b/xen/arch/x86/dom0_build.c
> @@ -568,7 +568,7 @@ int __init construct_dom0(struct domain
>  
>      if ( is_hvm_domain(d) )
>          rc = dom0_construct_pvh(d, image, image_headroom, initrd, cmdline);
> -    else if ( is_pv_domain(d) )
> +    else if ( is_pv_64bit_domain(d) || is_pv_32bit_domain(d) )

Urg, that's very confusing IMO, as I'm sure I would ask someone to
just use is_pv_domain without realizing. It needs at least a comment,
but even then I'm not sure I like it.

So that I understand it, the point to use those expressions instead of
is_pv_domain is to avoid calling dom0_construct_pv when CONFIG_PV is
not enabled?

Maybe it wold be better to instead use:

if ( IS_ENABLED(CONFIG_PV) && is_pv_domain(d) )

In any case I wonder if we should maybe aim to introduce a new type
for system domains, that's neither PV or HVM, in order to avoid having
system domains qualified as PV even when PV is compiled out.

>          rc = dom0_construct_pv(d, image, image_headroom, initrd, cmdline);
>      else
>          panic("Cannot construct Dom0. No guest interface available\n");
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1544,6 +1544,7 @@ arch_do_vcpu_op(
>   */
>  static void load_segments(struct vcpu *n)
>  {
> +#ifdef CONFIG_PV
>      struct cpu_user_regs *uregs = &n->arch.user_regs;
>      unsigned long gsb = 0, gss = 0;
>      bool compat = is_pv_32bit_vcpu(n);
> @@ -1709,6 +1710,7 @@ static void load_segments(struct vcpu *n
>          regs->cs            = FLAT_KERNEL_CS;
>          regs->rip           = pv->failsafe_callback_eip;
>      }
> +#endif
>  }
>  
>  /*
> @@ -1723,6 +1725,7 @@ static void load_segments(struct vcpu *n
>   */
>  static void save_segments(struct vcpu *v)
>  {
> +#ifdef CONFIG_PV
>      struct cpu_user_regs *regs = &v->arch.user_regs;
>  
>      read_sregs(regs);
> @@ -1748,6 +1751,7 @@ static void save_segments(struct vcpu *v
>          else
>              v->arch.pv.gs_base_user = gs_base;
>      }
> +#endif
>  }

Could you move {load,save}_segments to pv/domain.c and rename to
pv_{load,save}_segments and provide a dummy handler for !CONFIG_PV in
pv/domain.h?

Sorry it's slightly more work, but I think it's cleaner overall.

>  
>  void paravirt_ctxt_switch_from(struct vcpu *v)
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -408,13 +408,13 @@ long arch_do_domctl(
>      case XEN_DOMCTL_set_address_size:
>          if ( is_hvm_domain(d) )
>              ret = -EOPNOTSUPP;
> +        else if ( is_pv_64bit_domain(d) && domctl->u.address_size.size == 32 
> )
> +            ret = switch_compat(d);
>          else if ( is_pv_domain(d) )
>          {
>              if ( ((domctl->u.address_size.size == 64) && 
> !d->arch.pv.is_32bit) ||
>                   ((domctl->u.address_size.size == 32) &&  
> d->arch.pv.is_32bit) )
>                  ret = 0;
> -            else if ( domctl->u.address_size.size == 32 )
> -                ret = switch_compat(d);
>              else
>                  ret = -EINVAL;
>          }
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -985,7 +985,7 @@ static always_inline bool is_control_dom
>  
>  static always_inline bool is_pv_domain(const struct domain *d)
>  {
> -    return IS_ENABLED(CONFIG_PV) &&
> +    return IS_ENABLED(CONFIG_X86) &&
>          evaluate_nospec(!(d->options & XEN_DOMCTL_CDF_hvm));
>  }
>  
> @@ -1011,7 +1011,7 @@ static always_inline bool is_pv_32bit_vc
>  
>  static always_inline bool is_pv_64bit_domain(const struct domain *d)
>  {
> -    if ( !is_pv_domain(d) )
> +    if ( !IS_ENABLED(CONFIG_PV) || !is_pv_domain(d) )
>          return false;

I think overall is confusing to have a domain that returns true for
is_pv_domain but false for both is_pv_{64,32}bit_domain checks.

I know those are only the system domains, but it feels confusing and
could cause mistakes in the future IMO, as then we would have to
carefully think where to use ( is_pv_64bit_domain(d)
|| is_pv_32bit_domain(d) ) vs just using is_pv_domain(d), or
IS_ENABLED(CONFIG_PV) && is_pv_domain(d)

Thanks, Roger.



 


Rackspace

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