From patchwork Fri Dec 4 08:52:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 11951129 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D014DC4361A for ; Fri, 4 Dec 2020 08:53:14 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6763A227BF for ; Fri, 4 Dec 2020 08:53:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6763A227BF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=xen.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.44156.79203 (Exim 4.92) (envelope-from ) id 1kl6pr-0006Uh-2W; Fri, 04 Dec 2020 08:53:03 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 44156.79203; Fri, 04 Dec 2020 08:53:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kl6pq-0006UX-UL; Fri, 04 Dec 2020 08:53:02 +0000 Received: by outflank-mailman (input) for mailman id 44156; Fri, 04 Dec 2020 08:53:00 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kl6po-0006R7-P4 for xen-devel@lists.xenproject.org; Fri, 04 Dec 2020 08:53:00 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kl6po-000494-DL; Fri, 04 Dec 2020 08:53:00 +0000 Received: from host86-183-162-145.range86-183.btcentralplus.com ([86.183.162.145] helo=u2f063a87eabd5f.home) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kl6po-00081O-5d; Fri, 04 Dec 2020 08:53:00 +0000 X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:Content-Type:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=+0Al/tr4MJNf/ubHYvoVGtFEnTG6Fvjontp4axhb608=; b=K+uA/vPlVhnw6B2Cd4n3hb6Ytv LhfyaPwl70xjf38pluqEIy4yYZRLstm11FVEMiNZT6IMfJOFm0pOT31UGSb5RCzPdFJMwq4QV5u95 U0IZDX8TUWb+cgKYsVrN8BzNI2O9WTUOhdNpGbvCq3rN34dAVYfROOXizqVG75ec9rQ4=; From: Paul Durrant To: xen-devel@lists.xenproject.org Cc: Paul Durrant , Wei Liu , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v5 03/11] viridian: move IPI hypercall implementation into separate function Date: Fri, 4 Dec 2020 08:52:47 +0000 Message-Id: <20201204085255.26216-4-paul@xen.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201204085255.26216-1-paul@xen.org> References: <20201204085255.26216-1-paul@xen.org> MIME-Version: 1.0 From: Paul Durrant This patch moves the implementation of HVCALL_SEND_IPI that is currently inline in viridian_hypercall() into a new hvcall_ipi() function. The new function returns Xen errno values similarly to hvcall_flush(). Hence the errno translation code in viridial_hypercall() is generalized, removing the need for the local 'status' variable. NOTE: The formatting of the switch statement at the top of viridial_hypercall() is also adjusted as per CODING_STYLE. Signed-off-by: Paul Durrant --- Cc: Wei Liu Cc: Jan Beulich Cc: Andrew Cooper Cc: "Roger Pau Monné" v3: - Adjust prototype of new function v2: - Different formatting adjustment --- xen/arch/x86/hvm/viridian/viridian.c | 168 ++++++++++++++------------- 1 file changed, 87 insertions(+), 81 deletions(-) diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c index f0b3ee65e3aa..77e90b502c69 100644 --- a/xen/arch/x86/hvm/viridian/viridian.c +++ b/xen/arch/x86/hvm/viridian/viridian.c @@ -581,13 +581,72 @@ static int hvcall_flush(const union hypercall_input *input, return 0; } +static int hvcall_ipi(const union hypercall_input *input, + union hypercall_output *output, + paddr_t input_params_gpa, + paddr_t output_params_gpa) +{ + struct domain *currd = current->domain; + struct vcpu *v; + uint32_t vector; + uint64_t vcpu_mask; + + /* Get input parameters. */ + if ( input->fast ) + { + if ( input_params_gpa >> 32 ) + return -EINVAL; + + vector = input_params_gpa; + vcpu_mask = output_params_gpa; + } + else + { + struct { + uint32_t vector; + uint8_t target_vtl; + uint8_t reserved_zero[3]; + uint64_t vcpu_mask; + } input_params; + + if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa, + sizeof(input_params)) != HVMTRANS_okay ) + return -EINVAL; + + if ( input_params.target_vtl || + input_params.reserved_zero[0] || + input_params.reserved_zero[1] || + input_params.reserved_zero[2] ) + return -EINVAL; + + vector = input_params.vector; + vcpu_mask = input_params.vcpu_mask; + } + + if ( vector < 0x10 || vector > 0xff ) + return -EINVAL; + + for_each_vcpu ( currd, v ) + { + if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) ) + return -EINVAL; + + if ( !(vcpu_mask & (1ul << v->vcpu_id)) ) + continue; + + vlapic_set_irq(vcpu_vlapic(v), vector, 0); + } + + return 0; +} + int viridian_hypercall(struct cpu_user_regs *regs) { struct vcpu *curr = current; struct domain *currd = curr->domain; int mode = hvm_guest_x86_mode(curr); unsigned long input_params_gpa, output_params_gpa; - uint16_t status = HV_STATUS_SUCCESS; + int rc = 0; union hypercall_input input; union hypercall_output output = {}; @@ -600,11 +659,13 @@ int viridian_hypercall(struct cpu_user_regs *regs) input_params_gpa = regs->rdx; output_params_gpa = regs->r8; break; + case 4: input.raw = (regs->rdx << 32) | regs->eax; input_params_gpa = (regs->rbx << 32) | regs->ecx; output_params_gpa = (regs->rdi << 32) | regs->esi; break; + default: goto out; } @@ -616,92 +677,18 @@ int viridian_hypercall(struct cpu_user_regs *regs) * See section 14.5.1 of the specification. */ do_sched_op(SCHEDOP_yield, guest_handle_from_ptr(NULL, void)); - status = HV_STATUS_SUCCESS; break; case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE: case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST: - { - int rc = hvcall_flush(&input, &output, input_params_gpa, - output_params_gpa); - - switch ( rc ) - { - case 0: - break; - - case -ERESTART: - return HVM_HCALL_preempted; - - default: - ASSERT_UNREACHABLE(); - /* Fallthrough */ - case -EINVAL: - status = HV_STATUS_INVALID_PARAMETER; - break; - } - + rc = hvcall_flush(&input, &output, input_params_gpa, + output_params_gpa); break; - } case HVCALL_SEND_IPI: - { - struct vcpu *v; - uint32_t vector; - uint64_t vcpu_mask; - - status = HV_STATUS_INVALID_PARAMETER; - - /* Get input parameters. */ - if ( input.fast ) - { - if ( input_params_gpa >> 32 ) - break; - - vector = input_params_gpa; - vcpu_mask = output_params_gpa; - } - else - { - struct { - uint32_t vector; - uint8_t target_vtl; - uint8_t reserved_zero[3]; - uint64_t vcpu_mask; - } input_params; - - if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa, - sizeof(input_params)) != - HVMTRANS_okay ) - break; - - if ( input_params.target_vtl || - input_params.reserved_zero[0] || - input_params.reserved_zero[1] || - input_params.reserved_zero[2] ) - break; - - vector = input_params.vector; - vcpu_mask = input_params.vcpu_mask; - } - - if ( vector < 0x10 || vector > 0xff ) - break; - - for_each_vcpu ( currd, v ) - { - if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) ) - break; - - if ( !(vcpu_mask & (1ul << v->vcpu_id)) ) - continue; - - vlapic_set_irq(vcpu_vlapic(v), vector, 0); - } - - status = HV_STATUS_SUCCESS; + rc = hvcall_ipi(&input, &output, input_params_gpa, + output_params_gpa); break; - } default: gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n", @@ -714,12 +701,31 @@ int viridian_hypercall(struct cpu_user_regs *regs) * Given that return a status of 'invalid code' has not so far * caused any problems it's not worth logging. */ - status = HV_STATUS_INVALID_HYPERCALL_CODE; + rc = -EOPNOTSUPP; break; } out: - output.result = status; + switch ( rc ) + { + case 0: + break; + + case -ERESTART: + return HVM_HCALL_preempted; + + case -EOPNOTSUPP: + output.result = HV_STATUS_INVALID_HYPERCALL_CODE; + break; + + default: + ASSERT_UNREACHABLE(); + /* Fallthrough */ + case -EINVAL: + output.result = HV_STATUS_INVALID_PARAMETER; + break; + } + switch ( mode ) { case 8: