From patchwork Thu Oct 31 15:09:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 178199 Delivered-To: patch@linaro.org Received: by 2002:a92:409a:0:0:0:0:0 with SMTP id d26csp2980466ill; Thu, 31 Oct 2019 08:11:30 -0700 (PDT) X-Google-Smtp-Source: APXvYqwFDJduIF+Hi7436RnTCMdgDjYMRkC7cNWERk79PMXGqA3dTCFWatP87FJ+f+uLY2m0/1gd X-Received: by 2002:a6b:9245:: with SMTP id u66mr5524545iod.98.1572534690774; Thu, 31 Oct 2019 08:11:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572534690; cv=none; d=google.com; s=arc-20160816; b=fCURYd2qPAMD96EXFcrHzleGnQhq9hDq5qG00SvuLuRIElJSivOMlq5BTVo7cp3JQO w4Em0awDsQxuV4GwOYsX8AMaVWRahz+Z2rmBwAyC/ZDvteLZ3oZUAAmY569FyZT+wG4A FL16M8jfe6CIqI1QXCRmH+4YjI/FSrF/DFCdO5ns72qSKlrkwXH8Os0VFep8yALL/dWv oimFusu7JVgvm7JP0FgkZsIH6xivBfz4DCIt8y46vLg3UpLCadqNdbMCSDa3oMLa0xsp h0qujXoxT0HdKM/ZgVGIVByDS5pUn0pt1amNQ93+Dr+tQzepB9MsoM9mtSHzBRNNscOq WXag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from; bh=7runUlP1Nk1EmjGmCEuE7sEdIGG+cyukc2P9Wox5rps=; b=FewxjZOaZznRh5MXQwDLR+vobbZCYwMTHafFAj4WL7uEt04/ItUaS1J9aLLeVUtSMZ 1h0d0qV+A37rIu5sqvP8UWjbcdXiPWgTAJYayAxiY0hQhK0NY4SslFQ4f/67yA6oTiXs t+KNR1f/QTkISPcjykH04Okf1uZosaMeVvD0PtkUi49onh3Ln6bBb9+PY+YpvPfGBP7L /xK8cRiQfJNy5IyBzLx/pxhU8fRBNLntYHFYyU3PGRhEvWJ02mFSuffZpoCYGj+gkPBx GoX4uWeaMeDv+rD++lc7bakMF5pkvVzGC0NpUK3ZGYvTk82W0arLd4fWsZtKT1VNiqz7 EM+g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id t14si3264337ioj.81.2019.10.31.08.11.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 Oct 2019 08:11:30 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iQC5J-0006hq-HV; Thu, 31 Oct 2019 15:10:01 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iQC5I-0006gP-AQ for xen-devel@lists.xenproject.org; Thu, 31 Oct 2019 15:10:00 +0000 X-Inumbo-ID: 7898abd4-fbf0-11e9-954c-12813bfff9fa Received: from foss.arm.com (unknown [217.140.110.172]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTP id 7898abd4-fbf0-11e9-954c-12813bfff9fa; Thu, 31 Oct 2019 15:09:44 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6C0C868D; Thu, 31 Oct 2019 08:09:44 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (unknown [10.1.196.50]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 831D33F71E; Thu, 31 Oct 2019 08:09:43 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Thu, 31 Oct 2019 15:09:12 +0000 Message-Id: <20191031150922.22938-10-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191031150922.22938-1-julien.grall@arm.com> References: <20191031150922.22938-1-julien.grall@arm.com> Subject: [Xen-devel] [PATCH for-4.13 v4 09/19] xen/arm: traps: Rework entry/exit from the guest path 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: jgross@suse.com, Volodymyr Babchuk , Julien Grall , Stefano Stabellini , Julien Grall MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" At the moment, enter_hypervisor_head() and leave_hypervisor_tail() are used to deal with actions to be done before/after any guest request is handled. While they are meant to work in pair, the former is called for most of the traps, including traps from the same exception level (i.e. hypervisor) whilst the latter will only be called when returning to the guest. As pointed out, the enter_hypervisor_head() is not called from all the traps, so this makes potentially difficult to extend it for the dealing with same exception level. Furthermore, some assembly only path will require to call enter_hypervisor_tail(). So the function is now directly call by assembly in for guest vector only. This means that the check whether we are called in a guest trap can now be removed. Take the opportunity to rename enter_hypervisor_tail() and leave_hypervisor_tail() to something more meaningful and document them. This should help everyone to understand the purpose of the two functions. Note that enter_hypervisor_tail() does not take any parameters anymore as after the rework, the code does not use them anymore. Signed-off-by: Julien Grall Acked-by: Stefano Stabellini --- Changes in v4: - Add Stefano's acked-by Changes in v3: - Update the documentation on the callee side of leave_hypervisor_to_guest(). - Replace "interrupts" with "IRQ" Changes in v2: - Update in-code comment - Remove 'regs' parameter from enter_hypervisor_tail() - Add arm32 code --- xen/arch/arm/arm32/entry.S | 5 +++- xen/arch/arm/arm64/entry.S | 3 +- xen/arch/arm/traps.c | 71 ++++++++++++++++++++++------------------------ 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/xen/arch/arm/arm32/entry.S b/xen/arch/arm/arm32/entry.S index ec90cca093..5abff24e91 100644 --- a/xen/arch/arm/arm32/entry.S +++ b/xen/arch/arm/arm32/entry.S @@ -177,6 +177,9 @@ skip_check: .if \guest_iflags != n cpsie \guest_iflags .endif + + bl enter_hypervisor_from_guest + 2: /* We are ready to handle the trap, setup the registers and jump. */ adr lr, return_from_trap @@ -332,7 +335,7 @@ ENTRY(return_to_new_vcpu32) return_to_guest: mov r11, sp bic sp, #7 /* Align the stack pointer */ - bl leave_hypervisor_tail /* Disables interrupts on return */ + bl leave_hypervisor_to_guest /* Mask IRQ on return */ mov sp, r11 RESTORE_ONE_BANKED(SP_usr) /* LR_usr is the same physical register as lr and is restored below */ diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S index d94c13e7bf..97dc60210d 100644 --- a/xen/arch/arm/arm64/entry.S +++ b/xen/arch/arm/arm64/entry.S @@ -165,7 +165,7 @@ .if \hyp == 0 /* Guest mode */ - bl leave_hypervisor_tail /* Disables interrupts on return */ + bl leave_hypervisor_to_guest /* Mask IRQ on return */ exit_guest \compat @@ -192,6 +192,7 @@ "nop; nop", SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT) msr daifclr, \iflags + bl enter_hypervisor_from_guest mov x0, sp bl do_trap_\trap 1: diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 12c52a3860..adbedc2d15 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1984,47 +1984,46 @@ static inline bool needs_ssbd_flip(struct vcpu *v) cpu_require_ssbd_mitigation(); } -static void enter_hypervisor_head(struct cpu_user_regs *regs) +/* + * Actions that needs to be done after entering the hypervisor from the + * guest and before we handle any request. + */ +void enter_hypervisor_from_guest(void) { - if ( guest_mode(regs) ) - { - struct vcpu *v = current; + struct vcpu *v = current; - /* If the guest has disabled the workaround, bring it back on. */ - if ( needs_ssbd_flip(v) ) - arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2_FID, 1, NULL); + /* If the guest has disabled the workaround, bring it back on. */ + if ( needs_ssbd_flip(v) ) + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2_FID, 1, NULL); - /* - * If we pended a virtual abort, preserve it until it gets cleared. - * See ARM ARM DDI 0487A.j D1.14.3 (Virtual Interrupts) for details, - * but the crucial bit is "On taking a vSError interrupt, HCR_EL2.VSE - * (alias of HCR.VA) is cleared to 0." - */ - if ( v->arch.hcr_el2 & HCR_VA ) - v->arch.hcr_el2 = READ_SYSREG(HCR_EL2); + /* + * If we pended a virtual abort, preserve it until it gets cleared. + * See ARM ARM DDI 0487A.j D1.14.3 (Virtual Interrupts) for details, + * but the crucial bit is "On taking a vSError interrupt, HCR_EL2.VSE + * (alias of HCR.VA) is cleared to 0." + */ + if ( v->arch.hcr_el2 & HCR_VA ) + v->arch.hcr_el2 = READ_SYSREG(HCR_EL2); #ifdef CONFIG_NEW_VGIC - /* - * We need to update the state of our emulated devices using level - * triggered interrupts before syncing back the VGIC state. - * - * TODO: Investigate whether this is necessary to do on every - * trap and how it can be optimised. - */ - vtimer_update_irqs(v); - vcpu_update_evtchn_irq(v); + /* + * We need to update the state of our emulated devices using level + * triggered interrupts before syncing back the VGIC state. + * + * TODO: Investigate whether this is necessary to do on every + * trap and how it can be optimised. + */ + vtimer_update_irqs(v); + vcpu_update_evtchn_irq(v); #endif - vgic_sync_from_lrs(v); - } + vgic_sync_from_lrs(v); } void do_trap_guest_sync(struct cpu_user_regs *regs) { const union hsr hsr = { .bits = regs->hsr }; - enter_hypervisor_head(regs); - switch ( hsr.ec ) { case HSR_EC_WFI_WFE: @@ -2158,8 +2157,6 @@ void do_trap_hyp_sync(struct cpu_user_regs *regs) { const union hsr hsr = { .bits = regs->hsr }; - enter_hypervisor_head(regs); - switch ( hsr.ec ) { #ifdef CONFIG_ARM_64 @@ -2196,27 +2193,21 @@ void do_trap_hyp_sync(struct cpu_user_regs *regs) void do_trap_hyp_serror(struct cpu_user_regs *regs) { - enter_hypervisor_head(regs); - __do_trap_serror(regs, VABORT_GEN_BY_GUEST(regs)); } void do_trap_guest_serror(struct cpu_user_regs *regs) { - enter_hypervisor_head(regs); - __do_trap_serror(regs, true); } void do_trap_irq(struct cpu_user_regs *regs) { - enter_hypervisor_head(regs); gic_interrupt(regs, 0); } void do_trap_fiq(struct cpu_user_regs *regs) { - enter_hypervisor_head(regs); gic_interrupt(regs, 1); } @@ -2259,7 +2250,13 @@ static void check_for_vcpu_work(void) local_irq_disable(); } -void leave_hypervisor_tail(void) +/* + * Actions that needs to be done before entering the guest. This is the + * last thing executed before the guest context is fully restored. + * + * The function will return with IRQ masked. + */ +void leave_hypervisor_to_guest(void) { local_irq_disable();