Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hyperv: Convert hypercall statuses to linux error codes

Return linux-friendly error codes from hypercall helper functions,
which allows them to be used more flexibly.

Introduce hv_result_to_errno() for this purpose, which also handles
the special value U64_MAX returned from hv_do_hypercall().

Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <eahariha@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1740167795-13296-2-git-send-email-nunodasneves@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <1740167795-13296-2-git-send-email-nunodasneves@linux.microsoft.com>

authored by

Nuno Das Neves and committed by
Wei Liu
9d8731a1 3a7f7785

+40 -5
+34
drivers/hv/hv_common.c
··· 683 683 return HV_STATUS_INVALID_PARAMETER; 684 684 } 685 685 EXPORT_SYMBOL_GPL(hv_tdx_hypercall); 686 + 687 + /* Convert a hypercall result into a linux-friendly error code. */ 688 + int hv_result_to_errno(u64 status) 689 + { 690 + /* hv_do_hypercall() may return U64_MAX, hypercalls aren't possible */ 691 + if (unlikely(status == U64_MAX)) 692 + return -EOPNOTSUPP; 693 + /* 694 + * A failed hypercall is usually only recoverable (or loggable) near 695 + * the call site where the HV_STATUS_* code is known. So the errno 696 + * it gets converted to is not too useful further up the stack. 697 + * Provide a few mappings that could be useful, and revert to -EIO 698 + * as a fallback. 699 + */ 700 + switch (hv_result(status)) { 701 + case HV_STATUS_SUCCESS: 702 + return 0; 703 + case HV_STATUS_INVALID_HYPERCALL_CODE: 704 + case HV_STATUS_INVALID_HYPERCALL_INPUT: 705 + case HV_STATUS_INVALID_PARAMETER: 706 + case HV_STATUS_INVALID_PARTITION_ID: 707 + case HV_STATUS_INVALID_VP_INDEX: 708 + case HV_STATUS_INVALID_PORT_ID: 709 + case HV_STATUS_INVALID_CONNECTION_ID: 710 + case HV_STATUS_INVALID_LP_INDEX: 711 + case HV_STATUS_INVALID_REGISTER_VALUE: 712 + return -EINVAL; 713 + case HV_STATUS_INSUFFICIENT_MEMORY: 714 + return -ENOMEM; 715 + default: 716 + break; 717 + } 718 + return -EIO; 719 + }
+5 -5
drivers/hv/hv_proc.c
··· 88 88 local_irq_restore(flags); 89 89 if (!hv_result_success(status)) { 90 90 pr_err("Failed to deposit pages: %lld\n", status); 91 - ret = hv_result(status); 91 + ret = hv_result_to_errno(status); 92 92 goto err_free_allocations; 93 93 } 94 94 ··· 114 114 struct hv_output_add_logical_processor *output; 115 115 u64 status; 116 116 unsigned long flags; 117 - int ret = HV_STATUS_SUCCESS; 117 + int ret = 0; 118 118 119 119 /* 120 120 * When adding a logical processor, the hypervisor may return ··· 139 139 if (!hv_result_success(status)) { 140 140 pr_err("%s: cpu %u apic ID %u, %lld\n", __func__, 141 141 lp_index, apic_id, status); 142 - ret = hv_result(status); 142 + ret = hv_result_to_errno(status); 143 143 } 144 144 break; 145 145 } ··· 154 154 struct hv_create_vp *input; 155 155 u64 status; 156 156 unsigned long irq_flags; 157 - int ret = HV_STATUS_SUCCESS; 157 + int ret = 0; 158 158 159 159 /* Root VPs don't seem to need pages deposited */ 160 160 if (partition_id != hv_current_partition_id) { ··· 181 181 if (!hv_result_success(status)) { 182 182 pr_err("%s: vcpu %u, lp %u, %lld\n", __func__, 183 183 vp_index, flags, status); 184 - ret = hv_result(status); 184 + ret = hv_result_to_errno(status); 185 185 } 186 186 break; 187 187 }
+1
include/asm-generic/mshyperv.h
··· 297 297 return __cpumask_to_vpset(vpset, cpus, func); 298 298 } 299 299 300 + int hv_result_to_errno(u64 status); 300 301 void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die); 301 302 bool hv_is_hyperv_initialized(void); 302 303 bool hv_is_hibernation_supported(void);