From patchwork Thu May 23 10:20:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 10957209 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A32DB15A6 for ; Thu, 23 May 2019 10:21:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 876D42844C for ; Thu, 23 May 2019 10:21:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7BA8B28450; Thu, 23 May 2019 10:21:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7E26F2844C for ; Thu, 23 May 2019 10:21:55 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hTkpl-0003y3-1X; Thu, 23 May 2019 10:20:25 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hTkpj-0003xs-SS for xen-devel@lists.xenproject.org; Thu, 23 May 2019 10:20:23 +0000 X-Inumbo-ID: 5eb8b0c7-7d44-11e9-8980-bc764e045a96 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 5eb8b0c7-7d44-11e9-8980-bc764e045a96; Thu, 23 May 2019 10:20:21 +0000 (UTC) Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@MIAPEX02MSOL01.citrite.net Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=23.29.105.83; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 23.29.105.83 as permitted sender) identity=mailfrom; client-ip=23.29.105.83; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:23.29.105.83 ip4:162.221.156.83 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@MIAPEX02MSOL01.citrite.net) identity=helo; client-ip=23.29.105.83; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@MIAPEX02MSOL01.citrite.net"; x-conformance=sidf_compatible IronPort-SDR: 0fnzTbMbgyFuIDunANZiD+JZu7oJOYJ2W8GXToTvpz1seuHkxzaLYsKzdgGe73lUVpKe+3lhNR Lo94kL5FAU0DcMFR7FuZkDhUmJYfPraWCRrVsMr/Dufz/ketbvXiJns9faji0WQlWGDDDbuxOm 2+WnoEZe3qxLWg47t3oDaLwScTC3Auck1eCSnOzssShy1JdFyGcnwvpknNvzT2t1IDIXzMwzpt YcJu83S7ESoacgUErKerykBA3GG3JPztcZBHNPOvMZc6p/JGNeFMf5gE1CvzWJ2mxJrQabPKou FeQ= X-SBRS: 2.7 X-MesageID: 797642 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 23.29.105.83 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.60,502,1549947600"; d="scan'208";a="797642" From: Andrew Cooper To: Xen-devel Date: Thu, 23 May 2019 11:20:15 +0100 Message-ID: <1558606816-17842-2-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1558606816-17842-1-git-send-email-andrew.cooper3@citrix.com> References: <1558606816-17842-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 1/2] x86: init_hypercall_page() cleanup X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Tian , Wei Liu , Jan Beulich , Andrew Cooper , Jun Nakajima , Boris Ostrovsky , Brian Woods , Suravee Suthikulpanit , =?utf-8?q?Roger_Pau_?= =?utf-8?q?Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP The various pieces of the hypercall page infrastructure have grown organically over time and ended up in a bit of a mess. * Rename all functions to be of the form *_init_hypercall_page(). This makes them somewhat shorter, and means they can actually be grepped for in one go. * Move init_hypercall_page() to domain.c. The 64-bit traps.c isn't a terribly appropriate place for it to live. * Drop an obsolete comment from hvm_init_hypercall_page() and drop the domain parameter from hvm_funcs.init_hypercall_page() as it isn't necessary. * Rearrange the logic in the each function to avoid needing extra local variables, and to write the page in one single pass. No functional change. Signed-off-by: Andrew Cooper Reviewed-by: Wei Liu Acked-by: Jan Beulich Reviewed-by: Kevin Tian Acked-by: Brian Woods --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné CC: Jun Nakajima CC: Kevin Tian CC: Boris Ostrovsky CC: Suravee Suthikulpanit CC: Brian Woods --- xen/arch/x86/domain.c | 14 +++++++++ xen/arch/x86/domctl.c | 2 +- xen/arch/x86/hvm/hvm.c | 8 ++---- xen/arch/x86/hvm/svm/svm.c | 18 ++++++------ xen/arch/x86/hvm/vmx/vmx.c | 18 ++++++------ xen/arch/x86/pv/dom0_build.c | 3 +- xen/arch/x86/pv/hypercall.c | 63 ++++++++++++++++++++--------------------- xen/arch/x86/traps.c | 2 +- xen/arch/x86/x86_64/traps.c | 13 --------- xen/include/asm-x86/domain.h | 2 +- xen/include/asm-x86/hvm/hvm.h | 4 +-- xen/include/asm-x86/hypercall.h | 4 +-- 12 files changed, 73 insertions(+), 78 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index ac960dd..9485a17 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -175,6 +175,20 @@ static void noreturn continue_idle_domain(struct vcpu *v) reset_stack_and_jump(idle_loop); } +void init_hypercall_page(struct domain *d, void *ptr) +{ + memset(ptr, 0xcc, PAGE_SIZE); + + if ( is_hvm_domain(d) ) + hvm_init_hypercall_page(d, ptr); + else if ( is_pv_64bit_domain(d) ) + pv_ring3_init_hypercall_page(ptr); + else if ( is_pv_32bit_domain(d) ) + pv_ring1_init_hypercall_page(ptr); + else + ASSERT_UNREACHABLE(); +} + void dump_pageframe_info(struct domain *d) { struct page_info *page; diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 9bf2d08..7c6b809 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -517,7 +517,7 @@ long arch_do_domctl( } hypercall_page = __map_domain_page(page); - hypercall_page_initialise(d, hypercall_page); + init_hypercall_page(d, hypercall_page); unmap_domain_page(hypercall_page); put_page_and_type(page); diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 8993c2a..5666286 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3801,13 +3801,11 @@ static void hvm_latch_shinfo_size(struct domain *d) } } -/* Initialise a hypercall transfer page for a VMX domain using - paravirtualised drivers. */ -void hvm_hypercall_page_initialise(struct domain *d, - void *hypercall_page) +void hvm_init_hypercall_page(struct domain *d, void *ptr) { hvm_latch_shinfo_size(d); - alternative_vcall(hvm_funcs.init_hypercall_page, d, hypercall_page); + + alternative_vcall(hvm_funcs.init_hypercall_page, ptr); } void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 9f26493..cd6a6b3 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -916,17 +916,20 @@ static unsigned int svm_get_insn_bytes(struct vcpu *v, uint8_t *buf) return len; } -static void svm_init_hypercall_page(struct domain *d, void *hypercall_page) +static void svm_init_hypercall_page(void *p) { - char *p; - int i; + unsigned int i; - for ( i = 0; i < (PAGE_SIZE / 32); i++ ) + for ( i = 0; i < (PAGE_SIZE / 32); i++, p += 32 ) { - if ( i == __HYPERVISOR_iret ) + if ( unlikely(i == __HYPERVISOR_iret) ) + { + /* HYPERVISOR_iret isn't supported */ + *(u16 *)p = 0x0b0f; /* ud2 */ + continue; + } - p = (char *)(hypercall_page + (i * 32)); *(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */ *(u32 *)(p + 1) = i; *(u8 *)(p + 5) = 0x0f; /* vmmcall */ @@ -934,9 +937,6 @@ static void svm_init_hypercall_page(struct domain *d, void *hypercall_page) *(u8 *)(p + 7) = 0xd9; *(u8 *)(p + 8) = 0xc3; /* ret */ } - - /* Don't support HYPERVISOR_iret at the moment */ - *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */ } static inline void svm_tsc_ratio_save(struct vcpu *v) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 7d96678..0060310 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1262,17 +1262,20 @@ static void vmx_set_descriptor_access_exiting(struct vcpu *v, bool enable) vmx_vmcs_exit(v); } -static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page) +static void vmx_init_hypercall_page(void *p) { - char *p; - int i; + unsigned int i; - for ( i = 0; i < (PAGE_SIZE / 32); i++ ) + for ( i = 0; i < (PAGE_SIZE / 32); i++, p += 32 ) { - if ( i == __HYPERVISOR_iret ) + if ( unlikely(i == __HYPERVISOR_iret) ) + { + /* HYPERVISOR_iret isn't supported */ + *(u16 *)p = 0x0b0f; /* ud2 */ + continue; + } - p = (char *)(hypercall_page + (i * 32)); *(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */ *(u32 *)(p + 1) = i; *(u8 *)(p + 5) = 0x0f; /* vmcall */ @@ -1280,9 +1283,6 @@ static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page) *(u8 *)(p + 7) = 0xc1; *(u8 *)(p + 8) = 0xc3; /* ret */ } - - /* Don't support HYPERVISOR_iret at the moment */ - *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */ } static unsigned int vmx_get_interrupt_shadow(struct vcpu *v) diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index cef2d42..d48d014 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -738,8 +738,7 @@ int __init dom0_construct_pv(struct domain *d, rc = -1; goto out; } - hypercall_page_initialise( - d, (void *)(unsigned long)parms.virt_hypercall); + init_hypercall_page(d, _p(parms.virt_hypercall)); } /* Free temporary buffers. */ diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 5fdb8f9..0c84c0b 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -267,16 +267,28 @@ enum mc_disposition arch_do_multicall_call(struct mc_state *state) ? mc_continue : mc_preempt; } -void hypercall_page_initialise_ring3_kernel(void *hypercall_page) +void pv_ring3_init_hypercall_page(void *p) { - void *p = hypercall_page; unsigned int i; - /* Fill in all the transfer points with template machine code. */ for ( i = 0; i < (PAGE_SIZE / 32); i++, p += 32 ) { - if ( i == __HYPERVISOR_iret ) + if ( unlikely(i == __HYPERVISOR_iret) ) + { + /* + * HYPERVISOR_iret is special because it doesn't return and + * expects a special stack frame. Guests jump at this transfer + * point instead of calling it. + */ + *(u8 *)(p+ 0) = 0x51; /* push %rcx */ + *(u16 *)(p+ 1) = 0x5341; /* push %r11 */ + *(u8 *)(p+ 3) = 0x50; /* push %rax */ + *(u8 *)(p+ 4) = 0xb8; /* mov $__HYPERVISOR_iret, %eax */ + *(u32 *)(p+ 5) = __HYPERVISOR_iret; + *(u16 *)(p+ 9) = 0x050f; /* syscall */ + continue; + } *(u8 *)(p+ 0) = 0x51; /* push %rcx */ *(u16 *)(p+ 1) = 0x5341; /* push %r11 */ @@ -287,49 +299,34 @@ void hypercall_page_initialise_ring3_kernel(void *hypercall_page) *(u8 *)(p+12) = 0x59; /* pop %rcx */ *(u8 *)(p+13) = 0xc3; /* ret */ } - - /* - * HYPERVISOR_iret is special because it doesn't return and expects a - * special stack frame. Guests jump at this transfer point instead of - * calling it. - */ - p = hypercall_page + (__HYPERVISOR_iret * 32); - *(u8 *)(p+ 0) = 0x51; /* push %rcx */ - *(u16 *)(p+ 1) = 0x5341; /* push %r11 */ - *(u8 *)(p+ 3) = 0x50; /* push %rax */ - *(u8 *)(p+ 4) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ - *(u32 *)(p+ 5) = __HYPERVISOR_iret; - *(u16 *)(p+ 9) = 0x050f; /* syscall */ } -void hypercall_page_initialise_ring1_kernel(void *hypercall_page) +void pv_ring1_init_hypercall_page(void *p) { - void *p = hypercall_page; unsigned int i; - /* Fill in all the transfer points with template machine code. */ - for ( i = 0; i < (PAGE_SIZE / 32); i++, p += 32 ) { - if ( i == __HYPERVISOR_iret ) + if ( unlikely(i == __HYPERVISOR_iret) ) + { + /* + * HYPERVISOR_iret is special because it doesn't return and + * expects a special stack frame. Guests jump at this transfer + * point instead of calling it. + */ + *(u8 *)(p+ 0) = 0x50; /* push %eax */ + *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret, %eax */ + *(u32 *)(p+ 2) = __HYPERVISOR_iret; + *(u16 *)(p+ 6) = (HYPERCALL_VECTOR << 8) | 0xcd; /* int $xx */ + continue; + } *(u8 *)(p+ 0) = 0xb8; /* mov $,%eax */ *(u32 *)(p+ 1) = i; *(u16 *)(p+ 5) = (HYPERCALL_VECTOR << 8) | 0xcd; /* int $xx */ *(u8 *)(p+ 7) = 0xc3; /* ret */ } - - /* - * HYPERVISOR_iret is special because it doesn't return and expects a - * special stack frame. Guests jump at this transfer point instead of - * calling it. - */ - p = hypercall_page + (__HYPERVISOR_iret * 32); - *(u8 *)(p+ 0) = 0x50; /* push %eax */ - *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ - *(u32 *)(p+ 2) = __HYPERVISOR_iret; - *(u16 *)(p+ 6) = (HYPERCALL_VECTOR << 8) | 0xcd; /* int $xx */ } /* diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 05ddc39..ba1053f 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -828,7 +828,7 @@ int guest_wrmsr_xen(struct vcpu *v, uint32_t idx, uint64_t val) } hypercall_page = __map_domain_page(page); - hypercall_page_initialise(d, hypercall_page); + init_hypercall_page(d, hypercall_page); unmap_domain_page(hypercall_page); put_page_and_type(page); diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index cb4bf0a..23d9357 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -360,19 +360,6 @@ void subarch_percpu_traps_init(void) wrmsrl(MSR_SYSCALL_MASK, XEN_SYSCALL_MASK); } -void hypercall_page_initialise(struct domain *d, void *hypercall_page) -{ - memset(hypercall_page, 0xCC, PAGE_SIZE); - if ( is_hvm_domain(d) ) - hvm_hypercall_page_initialise(d, hypercall_page); - else if ( is_pv_64bit_domain(d) ) - hypercall_page_initialise_ring3_kernel(hypercall_page); - else if ( is_pv_32bit_domain(d) ) - hypercall_page_initialise_ring1_kernel(hypercall_page); - else - ASSERT_UNREACHABLE(); -} - /* * Local variables: * mode: C diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 214e44c..72dea80 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -83,7 +83,7 @@ void cpuid_policy_updated(struct vcpu *v); * Initialise a hypercall-transfer page. The given pointer must be mapped * in Xen virtual address space (accesses are not validated or checked). */ -void hypercall_page_initialise(struct domain *d, void *); +void init_hypercall_page(struct domain *d, void *); /************************************************/ /* shadow paging extension */ diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 1921422..b327bd2 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -152,7 +152,7 @@ struct hvm_function_table { void (*inject_event)(const struct x86_event *event); - void (*init_hypercall_page)(struct domain *d, void *hypercall_page); + void (*init_hypercall_page)(void *ptr); bool (*event_pending)(const struct vcpu *v); bool (*get_pending_event)(struct vcpu *v, struct x86_event *info); @@ -272,7 +272,7 @@ int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_mode); enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack); -void hvm_hypercall_page_initialise(struct domain *d, void *hypercall_page); +void hvm_init_hypercall_page(struct domain *d, void *ptr); void hvm_get_segment_register(struct vcpu *v, enum x86_segment seg, struct segment_register *reg); diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h index 49eb5f1..1cd8046 100644 --- a/xen/include/asm-x86/hypercall.h +++ b/xen/include/asm-x86/hypercall.h @@ -30,8 +30,8 @@ extern const hypercall_table_t pv_hypercall_table[]; void pv_hypercall(struct cpu_user_regs *regs); #endif -void hypercall_page_initialise_ring3_kernel(void *hypercall_page); -void hypercall_page_initialise_ring1_kernel(void *hypercall_page); +void pv_ring1_init_hypercall_page(void *ptr); +void pv_ring3_init_hypercall_page(void *ptr); /* * Both do_mmuext_op() and do_mmu_update(): From patchwork Thu May 23 10:20:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 10957211 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E1C3933 for ; Thu, 23 May 2019 10:21:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 459DB2844C for ; Thu, 23 May 2019 10:21:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 393D228450; Thu, 23 May 2019 10:21:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8F47B2844C for ; Thu, 23 May 2019 10:21:57 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hTkpq-0003zw-S8; Thu, 23 May 2019 10:20:30 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hTkpp-0003yw-Dy for xen-devel@lists.xenproject.org; Thu, 23 May 2019 10:20:29 +0000 X-Inumbo-ID: 62bed154-7d44-11e9-8980-bc764e045a96 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 62bed154-7d44-11e9-8980-bc764e045a96; Thu, 23 May 2019 10:20:28 +0000 (UTC) Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@MIAPEX02MSOL01.citrite.net Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=23.29.105.83; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 23.29.105.83 as permitted sender) identity=mailfrom; client-ip=23.29.105.83; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:23.29.105.83 ip4:162.221.156.83 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@MIAPEX02MSOL01.citrite.net) identity=helo; client-ip=23.29.105.83; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@MIAPEX02MSOL01.citrite.net"; x-conformance=sidf_compatible IronPort-SDR: v4K2/DLVv/NjO5oWz219apW/S5WQR8Y2W2pqno9Q/M60eGqMH8ciYtwmvrNrbFCBav6coZAFj3 enVWNtpMzDtRqq8el45aSdvpkjYokgqZKvhjfjrtjzlJdjldTLLtwnTvQwxrkSKbsoih7JX6YR QwzdF6fkkDyHos6MuyQ19Bz+CfxNhDyKYT24AwgYzet22eYsTC6+zjhFLg51Ajti8bf9i972iJ +o2DIdCwr/ay+XALenHUAFZA0GkzC4IuXcjGVNdGv6CeNfzhX6iWZzFioDgb0cJj6+d/oy3Aqz h0k= X-SBRS: 2.7 X-MesageID: 820874 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 23.29.105.83 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.60,502,1549947600"; d="scan'208";a="820874" From: Andrew Cooper To: Xen-devel Date: Thu, 23 May 2019 11:20:16 +0100 Message-ID: <1558606816-17842-3-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1558606816-17842-1-git-send-email-andrew.cooper3@citrix.com> References: <1558606816-17842-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 2/2] docs: Introduce some hypercall page documentation X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Tim Deegan , Julien Grall , Jan Beulich , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This also introduced the top-level Guest Documentation section. Signed-off-by: Andrew Cooper Acked-by: Wei Liu --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Konrad Rzeszutek Wilk CC: Stefano Stabellini CC: Tim Deegan CC: Wei Liu CC: Julien Grall The rendered version can be viewed at: https://andrewcoop-xen.readthedocs.io/en/docs-devel/guest-guide/hypercall-abi.html --- docs/guest-guide/hypercall-abi.rst | 127 +++++++++++++++++++++++++++++++++++++ docs/guest-guide/index.rst | 10 +++ docs/index.rst | 13 ++++ 3 files changed, 150 insertions(+) create mode 100644 docs/guest-guide/hypercall-abi.rst create mode 100644 docs/guest-guide/index.rst diff --git a/docs/guest-guide/hypercall-abi.rst b/docs/guest-guide/hypercall-abi.rst new file mode 100644 index 0000000..9862b14 --- /dev/null +++ b/docs/guest-guide/hypercall-abi.rst @@ -0,0 +1,127 @@ +Hypercall ABI +============= + +Hypercalls are system calls to Xen. Two modes of guest operation are +supported, and up to 6 individual parameters are supported. + +Hypercalls may only be issued by kernel-level software [1]_. + +Registers +--------- + +The registers used for hypercalls depends on the operating mode of the guest. + +.. list-table:: + :header-rows: 1 + + * - ABI + - Hypercall Index + - Parameters (1 - 6) + - Result + + * - 64bit + - %rax + - %rdi %rsi %rdx %r10 %r8 %r9 + - %rax + + * - 32bit + - %eax + - %ebx %ecx %edx %esi %edi %ebp + - %eax + +32 and 64bit PV guests have an ABI fixed by their guest type. The ABI for an +HVM guest depends on whether the vCPU is operating in a 64bit segment or not +[2]_. + + +Parameters +---------- + +Different hypercalls take a different number of parameters. Each hypercall +potentially clobbers each of its parameter registers; a guest may not rely on +the parameter registers staying the same. A debug build of Xen checks this by +deliberately poisoning the parameter registers before returning back to the +guest. + + +Mode transfer +------------- + +The exact sequence of instructions required to issue a hypercall differs +between virtualisation mode and hardware vendor. + +.. list-table:: + :header-rows: 1 + + * - Guest + - Transfer instruction + + * - 32bit PV + - INT $0x82 + + * - 64bit PV + - SYSCALL + + * - Intel HVM + - VMCALL + + * - AMD HVM + - VMMCALL + +To abstract away the details, Xen implements an interface known as the +Hypercall Page. This allows a guest to make a hypercall without needing to +perform mode-specific or vendor-specific setup. + + +Hypercall Page +============== + +The hypercall page is a page of guest RAM into which Xen will write suitable +transfer stubs. + +Creating a hypercall page is an isolated operation from Xen's point of view. +It is the guests responsibility to ensure that the hypercall page, once +written by Xen, is mapped with executable permissions so it may be used. +Multiple hypercall pages may be created by the guest, if it wishes. + +The stubs are arranged by hypercall index, and start on 32-byte boundaries. +To invoke a specific hypercall, ``call`` the relevant stub [3]_: + +.. code-block:: none + + call hypercall_page + index * 32 + +There result is an ABI which is invariant of the exact operating mode or +hardware vendor. This is intended to simplify guest kernel interfaces by +abstracting away the details of how it is currently running. + + +Creating Hypercall Pages +------------------------ + +Guests which are started using the PV boot protocol may set set +``XEN_ELFNOTE_HYPERCALL_PAGE`` to have the nominated page written as a +hypercall page during construction. This mechanism is common for PV guests, +and allows hypercalls to be issued with no additional setup. + +Any guest can locate the Xen CPUID leaves and read the *hypercall transfer +page* information, which specifies an MSR that can be used to create +additional hypercall pages. When a guest physical address is written to the +MSR, Xen writes a hypercall page into the nominated guest page. This +mechanism is common for HVM guests which are typically started via legacy +means. + + +.. rubric:: Footnotes + +.. [1] For HVM guests, ``HVMOP_guest_request_vm_event`` may be configured to + be usable from userspace, but this behaviour is not default. + +.. [2] While it is possible to use compatibility mode segments in a 64bit + kernel, hypercalls issues from such a mode will be interpreted with the + 32bit ABI. Such a setup is not expected in production scenarios. + +.. [3] ``HYPERCALL_iret`` is special. It is only implemented for PV guests + and takes all its parameters on the stack. This stub should be + ``jmp``'d to, rather than ``call``'d. HVM guests have this stub + implemented as ``ud2a`` to prevent accidental use. diff --git a/docs/guest-guide/index.rst b/docs/guest-guide/index.rst new file mode 100644 index 0000000..c657332 --- /dev/null +++ b/docs/guest-guide/index.rst @@ -0,0 +1,10 @@ +Guest documentation +=================== + +x86 +--- + +.. toctree:: + :maxdepth: 2 + + hypercall-abi diff --git a/docs/index.rst b/docs/index.rst index 9e2e256..31bb892 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,6 +21,19 @@ configure the system. admin-guide/index +Guest documentation +------------------- + +This documentation concerns the APIs and ABIs available to guests. It is +intended for OS developers trying to use a Xen feature, and for Xen developers +to avoid breaking things. + +.. toctree:: + :maxdepth: 3 + + guest-guide/index + + Hypervisor developer documentation ----------------------------------