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

Re: [XEN][PATCH v3] xen/x86: guest_access: optimize raw_x_guest() for PV and HVM combinations


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Grygorii Strashko <grygorii_strashko@xxxxxxxx>
  • Date: Tue, 11 Nov 2025 19:52:03 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=1aezGidGgtshjyPLhbIqrw5klDLEFqQlUAJ01YoMbnE=; b=lG+DzXuHChan2M10ryB3GsEU+7TEDvqpHOWGPy4XrDIuiS3GP9pCEOa2ItyCrzDc2UoGEZrd5VTT8bFXHH7UfWnid5pOTOpcsR3j/zEskPeLfjNk2wf4RV1I2++b4hKmV0JulftHmJUitEVXfYAnGLCVfnqrnjfWzjlK8LQ15rVfZuOFfUSGJIspnq0crFJnsUS54nBB/QgBxdEL4NELvCF47HbJjlp8lUDOGDPdDtcaYAea1vsyiSjswpbBQA68D58pOY0Fe5c1GYt6LJD8124z330kOSkp50uGt+X7iEQVrBIrFo5HiVp3ykLwOHXJxWDdbJUPs3RclgRTykRSfQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=zHnV3nqwauEKf1g00Fu5qHVt/n4CmIq3EJGkJ+Ri43dWWLh0fP4Ba5JjcRGw0QokoQHNWE1DC1WtWczjwEU5NRz3KgG75gvL1Aw+D8waKHhoG1N4nDWwEr6OUz63j2v8W6RkGKTbKRdZcrdHq0un4M+PL47VQp/0qqgLJL1X1iz1dm36+lDW+xR9wOpziPFNxH9d5hjT72Q0MQZBvMM5Q4PhSzV9gvHFvW17Muxckn9a9r5TubRIlGk46RCsPNmJ+P8IBOqBO9CmNr0asxoRmYnasMLytyV/Qt7k3kHBIQvsnvMh67LoxBaVP413ifNgrd1hx6BpzNQnN6JZ84rg9g==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Jason Andryuk <jason.andryuk@xxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, "Lira, Victor M" <victlira@xxxxxxx>
  • Delivery-date: Tue, 11 Nov 2025 17:52:23 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>



On 10.11.25 09:11, Jan Beulich wrote:
On 07.11.2025 19:17, Grygorii Strashko wrote:
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -71,7 +71,7 @@ obj-y += time.o
  obj-y += traps-setup.o
  obj-y += traps.o
  obj-$(CONFIG_INTEL) += tsx.o
-obj-y += usercopy.o
+obj-$(CONFIG_PV) += usercopy.o

Imo, if this was indeed doable (see below) the file would rather want moving
to pv/.

I've tried it :( But at that time it has failed for me because of macro magic 
which uses
"# include __FILE__".

Now I see that additional Makefile line:

# Allows usercopy.c to include itself
$(obj)/usercopy.o: CFLAGS-y += -iquote .

need to be moved also.


--- a/xen/arch/x86/include/asm/guest_access.h
+++ b/xen/arch/x86/include/asm/guest_access.h
@@ -13,26 +13,64 @@
  #include <asm/hvm/guest_access.h>
/* Raw access functions: no type checking. */
-#define raw_copy_to_guest(dst, src, len)        \
-    (is_hvm_vcpu(current) ?                     \
-     copy_to_user_hvm((dst), (src), (len)) :    \
-     copy_to_guest_pv(dst, src, len))
-#define raw_copy_from_guest(dst, src, len)      \
-    (is_hvm_vcpu(current) ?                     \
-     copy_from_user_hvm((dst), (src), (len)) :  \
-     copy_from_guest_pv(dst, src, len))
-#define raw_clear_guest(dst,  len)              \
-    (is_hvm_vcpu(current) ?                     \
-     clear_user_hvm((dst), (len)) :             \
-     clear_guest_pv(dst, len))
-#define __raw_copy_to_guest(dst, src, len)      \
-    (is_hvm_vcpu(current) ?                     \
-     copy_to_user_hvm((dst), (src), (len)) :    \
-     __copy_to_guest_pv(dst, src, len))
-#define __raw_copy_from_guest(dst, src, len)    \
-    (is_hvm_vcpu(current) ?                     \
-     copy_from_user_hvm((dst), (src), (len)) :  \
-     __copy_from_guest_pv(dst, src, len))
+static inline bool raw_use_hvm_access(const struct vcpu *v)
+{
+    return IS_ENABLED(CONFIG_HVM) && (!IS_ENABLED(CONFIG_PV) || 
is_hvm_vcpu(v));
+}

Without a full audit (likely tedious and error prone) this still is a
behavioral change for some (likely unintended) use against a system domain
(likely the idle one): With HVM=y PV=n we'd suddenly use the HVM accessor
there. IOW imo the "system domains are implicitly PV" aspect wants
retaining, even if only "just in case". It's okay not to invoke the PV
accessor (but return "len" instead), but it's not okay to invoke the HVM
one.


This patch is subset of "constify is_hvm_domain() for PV=n case" attempts.

It was made under assumption that:
"System domains do not have Guests running, so can't initiate hypecalls and
 can not be users of copy_to/from_user() routines. There are no Guest and no user 
memory".
[IDLE, COW, IO, XEN]

If above assumption is correct - this patch was assumed safe.

if not - it all make no sense, probably.
+static inline unsigned int raw_copy_to_guest(void *dst, const void *src,
+                                             unsigned int len)
+{
+    if ( raw_use_hvm_access(current) )
+        return copy_to_user_hvm(dst, src, len);
+    else if ( IS_ENABLED(CONFIG_PV) )
+        return copy_to_guest_pv(dst, src, len);
+    else
+        return len;
+}
+
+static inline unsigned int raw_copy_from_guest(void *dst, const void *src,
+                                               unsigned int len)
+{
+    if ( raw_use_hvm_access(current) )
+        return copy_from_user_hvm(dst, src, len);
+    else if ( IS_ENABLED(CONFIG_PV) )
+        return copy_from_guest_pv(dst, src, len);
+    else
+        return len;
+}
+
+static inline unsigned int raw_clear_guest(void *dst, unsigned int len)
+{
+    if ( raw_use_hvm_access(current) )
+        return clear_user_hvm(dst, len);
+    else if ( IS_ENABLED(CONFIG_PV) )
+        return clear_guest_pv(dst, len);
+    else
+        return len;
+}
+
+static inline unsigned int __raw_copy_to_guest(void *dst, const void *src,
+                                               unsigned int len)
+{
+    if ( raw_use_hvm_access(current) )
+        return copy_to_user_hvm(dst, src, len);
+    else if ( IS_ENABLED(CONFIG_PV) )
+        return __copy_to_guest_pv(dst, src, len);
+    else
+        return len;
+}
+
+static inline unsigned int __raw_copy_from_guest(void *dst, const void *src,
+                                                 unsigned int len)
+{
+    if ( raw_use_hvm_access(current) )
+        return copy_from_user_hvm(dst, src, len);
+    else if ( IS_ENABLED(CONFIG_PV) )
+        return __copy_from_guest_pv(dst, src, len);
+    else
+        return len;
+}

I have to admit that I'm not quite happy about the redundancy here (leaving
aside the imo Misra-conflicting uses of "else"). It looks as if some macro-
ization could still help. Not sure what others think, though.



Just an observation note:
 From my recent experience I see that macro-magic makes Coverage report (gcov)
to provide not exactly correct results in terms of code lines coverage at least 
:(
For example, for usercopy.o: 7 functions reported, but lines coverage is 
accounted
only till '# undef GUARD".


--
Best regards,
-grygorii




 


Rackspace

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