x86/pv: Short-circuit is_pv_{32,64}bit_domain() in !CONFIG_PV32 builds
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 17 Apr 2020 14:36:06 +0000 (15:36 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 29 Apr 2020 20:13:00 +0000 (21:13 +0100)
... and move arch.is_32bit_pv into the pv union while at it.

Adjust the impacted code to use true/false, dropping the hunk
pv_domain_initialise() which is storing 0 into an already zeroed
datastructure.

Bloat-o-meter reports the following net savings with some notable differences
highlighted:

  add/remove: 4/6 grow/shrink: 5/76 up/down: 1955/-18792 (-16837)
  Function                                     old     new   delta
  ...
  pv_vcpu_initialise                           411     158    -253
  guest_cpuid                                 1837    1584    -253
  pv_hypercall                                 579     297    -282
  check_descriptor                             427     130    -297
  _get_page_type                              5915    5202    -713
  arch_get_info_guest                         2225    1195   -1030
  context_switch                              3831    2635   -1196
  dom0_construct_pv                          10284    8939   -1345
  arch_set_info_guest                         5564    3267   -2297
  Total: Before=3079563, After=3062726, chg -0.55%

In principle, DOMAIN_is_32bit_pv should be based on CONFIG_PV32, but the
assembly code is going to need further untangling before that becomes easy to
do.  For now, use CONFIG_PV as missed accidentally by c/s ec651bd2460 "x86:
make entry point code build when !CONFIG_PV".

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wl@xen.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/domctl.c
xen/arch/x86/pv/domain.c
xen/arch/x86/pv/hypercall.c
xen/arch/x86/x86_64/asm-offsets.c
xen/include/asm-x86/domain.h
xen/include/xen/sched.h

index 03dffa5ecf0c538d673907cf6ef97fed6705880b..8c55db2f693e734659dfa47d835359fd4a52550e 100644 (file)
@@ -577,8 +577,8 @@ long arch_do_domctl(
             ret = -EOPNOTSUPP;
         else if ( is_pv_domain(d) )
         {
-            if ( ((domctl->u.address_size.size == 64) && !d->arch.is_32bit_pv) ||
-                 ((domctl->u.address_size.size == 32) && d->arch.is_32bit_pv) )
+            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);
index 3579dc063ea5ea7d9e7d1f29edca52bb4c7c2039..0a4a5bd00182f4df204dfd8397938248280e3c5e 100644 (file)
@@ -214,7 +214,7 @@ int switch_compat(struct domain *d)
         return 0;
 
     d->arch.has_32bit_shinfo = 1;
-    d->arch.is_32bit_pv = 1;
+    d->arch.pv.is_32bit = true;
 
     for_each_vcpu( d, v )
     {
@@ -234,7 +234,7 @@ int switch_compat(struct domain *d)
     return 0;
 
  undo_and_fail:
-    d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0;
+    d->arch.pv.is_32bit = d->arch.has_32bit_shinfo = false;
     for_each_vcpu( d, v )
     {
         free_compat_arg_xlat(v);
@@ -352,9 +352,6 @@ int pv_domain_initialise(struct domain *d)
 
     d->arch.ctxt_switch = &pv_csw;
 
-    /* 64-bit PV guest by default. */
-    d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0;
-
     d->arch.pv.xpti = is_hardware_domain(d) ? opt_xpti_hwdom : opt_xpti_domu;
 
     if ( !is_pv_32bit_domain(d) && use_invpcid && cpu_has_pcid )
index 686a7f2c5c09476db2936138c5e96fc50b40246d..b0d1d0ed773c89fb43b37560e10b6933c6fe4afe 100644 (file)
@@ -302,6 +302,7 @@ void pv_ring3_init_hypercall_page(void *p)
     }
 }
 
+#ifdef CONFIG_PV32
 void pv_ring1_init_hypercall_page(void *p)
 {
     unsigned int i;
@@ -329,6 +330,7 @@ void pv_ring1_init_hypercall_page(void *p)
         *(u8  *)(p+ 7) = 0xc3;    /* ret */
     }
 }
+#endif
 
 /*
  * Local variables:
index 500df7a3e7c7af247c5d4252482d5aa22f249469..9f66a69be7641262a69beca49cb20f3e0c640424 100644 (file)
@@ -98,8 +98,10 @@ void __dummy__(void)
     OFFSET(VCPU_nsvm_hap_enabled, struct vcpu, arch.hvm.nvcpu.u.nsvm.ns_hap_enabled);
     BLANK();
 
-    OFFSET(DOMAIN_is_32bit_pv, struct domain, arch.is_32bit_pv);
+#ifdef CONFIG_PV
+    OFFSET(DOMAIN_is_32bit_pv, struct domain, arch.pv.is_32bit);
     BLANK();
+#endif
 
     OFFSET(VCPUINFO_upcall_pending, struct vcpu_info, evtchn_upcall_pending);
     OFFSET(VCPUINFO_upcall_mask, struct vcpu_info, evtchn_upcall_mask);
index b10d74fb575baa7ec8c7babce0d9706e85efaa5f..5b6d909266b2e944773523de1c5d709868137b98 100644 (file)
@@ -262,6 +262,8 @@ struct pv_domain
 
     atomic_t nr_l4_pages;
 
+    /* Is a 32-bit PV guest? */
+    bool is_32bit;
     /* XPTI active? */
     bool xpti;
     /* Use PCID feature? */
@@ -341,8 +343,6 @@ struct arch_domain
     /* NB. protected by d->event_lock and by irq_desc[irq].lock */
     struct radix_tree_root irq_pirq;
 
-    /* Is a 32-bit PV (non-HVM) guest? */
-    bool_t is_32bit_pv;
     /* Is shared-info page in 32-bit format? */
     bool_t has_32bit_shinfo;
 
index 195e7ee583e72394c142c6165d9e8df8baa496f1..6101761d25b74f092610e5401cf6c40d6cfcfe86 100644 (file)
@@ -985,7 +985,11 @@ static always_inline bool is_pv_vcpu(const struct vcpu *v)
 #ifdef CONFIG_COMPAT
 static always_inline bool is_pv_32bit_domain(const struct domain *d)
 {
-    return is_pv_domain(d) && d->arch.is_32bit_pv;
+#ifdef CONFIG_PV32
+    return is_pv_domain(d) && d->arch.pv.is_32bit;
+#else
+    return false;
+#endif
 }
 
 static always_inline bool is_pv_32bit_vcpu(const struct vcpu *v)
@@ -995,7 +999,14 @@ static always_inline bool is_pv_32bit_vcpu(const struct vcpu *v)
 
 static always_inline bool is_pv_64bit_domain(const struct domain *d)
 {
-    return is_pv_domain(d) && !d->arch.is_32bit_pv;
+    if ( !is_pv_domain(d) )
+        return false;
+
+#ifdef CONFIG_PV32
+    return !d->arch.pv.is_32bit;
+#else
+    return true;
+#endif
 }
 
 static always_inline bool is_pv_64bit_vcpu(const struct vcpu *v)