[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] viridian: move IPI hypercall implementation into separate function
commit 905d931bcafa7be77dfe21ee5a839286bb52cfaa Author: Paul Durrant <pdurrant@xxxxxxxxxx> AuthorDate: Fri Dec 4 13:13:41 2020 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Fri Dec 4 13:13:41 2020 +0100 viridian: move IPI hypercall implementation into separate function 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 <pdurrant@xxxxxxxxxx> Acked-by: Wei Liu <wl@xxxxxxx> --- 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 f0b3ee65e3..77e90b502c 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: -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |