|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |