[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 |