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

[RFC PATCH 03/16] x86/hvm: Add support for physical address ABI



Guest can tag their hypercalls with 0x40000000 in order to use this
alternative ABI that uses physical addresses instead of linear ones.

Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
This one is based on the "HVMv2 ABI" RFC, but reworked in a way that is more
compatible with existing guest (guest need to opt-in abi for a specific
hypercall).

Andrew has some plans regarding making a better HVM ABI for that, but it is
a first start for this RFC.
---
 xen/arch/x86/hvm/hvm.c       | 17 ++++++++++++++---
 xen/arch/x86/hvm/hypercall.c | 17 +++++++++++++----
 xen/include/xen/sched.h      |  2 ++
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 4cb2e13046..0e7c453b24 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3497,7 +3497,11 @@ unsigned int copy_to_user_hvm(void *to, const void 
*from, unsigned int len)
         return 0;
     }
 
-    rc = hvm_copy_to_guest_linear((unsigned long)to, from, len, 0, NULL);
+    if ( evaluate_nospec(current->hcall_physaddr) )
+        rc = hvm_copy_to_guest_phys((unsigned long)to, from, len, current);
+    else
+        rc = hvm_copy_to_guest_linear((unsigned long)to, from, len, 0, NULL);
+
     return rc ? len : 0; /* fake a copy_to_user() return code */
 }
 
@@ -3511,7 +3515,10 @@ unsigned int clear_user_hvm(void *to, unsigned int len)
         return 0;
     }
 
-    rc = hvm_copy_to_guest_linear((unsigned long)to, NULL, len, 0, NULL);
+    if ( evaluate_nospec(current->hcall_physaddr) )
+        rc = hvm_copy_to_guest_phys((unsigned long)to, NULL, len, current);
+    else
+        rc = hvm_copy_to_guest_linear((unsigned long)to, NULL, len, 0, NULL);
 
     return rc ? len : 0; /* fake a clear_user() return code */
 }
@@ -3526,7 +3533,11 @@ unsigned int copy_from_user_hvm(void *to, const void 
*from, unsigned int len)
         return 0;
     }
 
-    rc = hvm_copy_from_guest_linear(to, (unsigned long)from, len, 0, NULL);
+    if ( evaluate_nospec(current->hcall_physaddr) )
+        rc = hvm_copy_from_guest_phys(to, (unsigned long)from, len);
+    else
+        rc = hvm_copy_from_guest_linear(to, (unsigned long)from, len, 0, NULL);
+
     return rc ? len : 0; /* fake a copy_from_user() return code */
 }
 
diff --git a/xen/arch/x86/hvm/hypercall.c b/xen/arch/x86/hvm/hypercall.c
index 6f8dfdff4a..b891089cda 100644
--- a/xen/arch/x86/hvm/hypercall.c
+++ b/xen/arch/x86/hvm/hypercall.c
@@ -160,8 +160,13 @@ int hvm_hypercall(struct cpu_user_regs *regs)
         HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%lu(%lx, %lx, %lx, %lx, %lx)",
                     eax, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8);
 
-        call_handlers_hvm64(eax, regs->rax, regs->rdi, regs->rsi, regs->rdx,
-                            regs->r10, regs->r8);
+        if ( eax & 0x40000000U )
+            curr->hcall_physaddr = true;
+
+        call_handlers_hvm64(eax & ~0x40000000U, regs->rax, regs->rdi, 
regs->rsi,
+                            regs->rdx, regs->r10, regs->r8);
+
+        curr->hcall_physaddr = false;
 
         if ( !curr->hcall_preempted && regs->rax != -ENOSYS )
             clobber_regs(regs, eax, hvm, 64);
@@ -172,9 +177,13 @@ int hvm_hypercall(struct cpu_user_regs *regs)
                     regs->ebx, regs->ecx, regs->edx, regs->esi, regs->edi);
 
         curr->hcall_compat = true;
-        call_handlers_hvm32(eax, regs->eax, regs->ebx, regs->ecx, regs->edx,
-                            regs->esi, regs->edi);
+        if ( eax & 0x40000000U )
+            curr->hcall_physaddr = true;
+
+        call_handlers_hvm32(eax & ~0x40000000U, regs->eax, regs->ebx, 
regs->ecx,
+                            regs->edx, regs->esi, regs->edi);
         curr->hcall_compat = false;
+        curr->hcall_physaddr = false;
 
         if ( !curr->hcall_preempted && regs->eax != -ENOSYS )
             clobber_regs(regs, eax, hvm, 32);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 559d201e0c..4ce9253284 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -240,6 +240,8 @@ struct vcpu
     bool             hcall_compat;
     /* Physical runstate area registered via compat ABI? */
     bool             runstate_guest_area_compat;
+    /* A hypercall is using the physical address ABI? */
+    bool             hcall_physaddr;
 #endif
 
 #ifdef CONFIG_IOREQ_SERVER
-- 
2.49.0



Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

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