Commit 753ed9c9 authored by Joseph Salisbury's avatar Joseph Salisbury Committed by Wei Liu
Browse files

drivers: hv: Create a consistent pattern for checking Hyper-V hypercall status



There is not a consistent pattern for checking Hyper-V hypercall status.
Existing code uses a number of variants.  The variants work, but a consistent
pattern would improve the readability of the code, and be more conformant
to what the Hyper-V TLFS says about hypercall status.

Implemented new helper functions hv_result(), hv_result_success(), and
hv_repcomp().  Changed the places where hv_do_hypercall() and related variants
are used to use the helper functions.

Signed-off-by: default avatarJoseph Salisbury <joseph.salisbury@microsoft.com>
Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/1618620183-9967-2-git-send-email-joseph.salisbury@linux.microsoft.com


Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent 6523592c
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
	struct hv_send_ipi_ex *ipi_arg;
	unsigned long flags;
	int nr_bank = 0;
	int ret = 1;
	u64 status = HV_STATUS_INVALID_PARAMETER;

	if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
		return false;
@@ -130,19 +130,19 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
	if (!nr_bank)
		ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;

	ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
	status = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
			      ipi_arg, NULL);

ipi_mask_ex_done:
	local_irq_restore(flags);
	return ((ret == 0) ? true : false);
	return hv_result_success(status);
}

static bool __send_ipi_mask(const struct cpumask *mask, int vector)
{
	int cur_cpu, vcpu;
	struct hv_send_ipi ipi_arg;
	int ret = 1;
	u64 status;

	trace_hyperv_send_ipi_mask(mask, vector);

@@ -186,9 +186,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
		__set_bit(vcpu, (unsigned long *)&ipi_arg.cpu_mask);
	}

	ret = hv_do_fast_hypercall16(HVCALL_SEND_IPI, ipi_arg.vector,
	status = hv_do_fast_hypercall16(HVCALL_SEND_IPI, ipi_arg.vector,
				     ipi_arg.cpu_mask);
	return ((ret == 0) ? true : false);
	return hv_result_success(status);

do_ex_hypercall:
	return __send_ipi_mask_ex(mask, vector);
@@ -197,6 +197,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
static bool __send_ipi_one(int cpu, int vector)
{
	int vp = hv_cpu_number_to_vp_number(cpu);
	u64 status;

	trace_hyperv_send_ipi_one(cpu, vector);

@@ -209,7 +210,8 @@ static bool __send_ipi_one(int cpu, int vector)
	if (vp >= 64)
		return __send_ipi_mask_ex(cpumask_of(cpu), vector);

	return !hv_do_fast_hypercall16(HVCALL_SEND_IPI, vector, BIT_ULL(vp));
	status = hv_do_fast_hypercall16(HVCALL_SEND_IPI, vector, BIT_ULL(vp));
	return hv_result_success(status);
}

static void hv_send_ipi(int cpu, int vector)
+1 −1
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ static void __init hv_get_partition_id(void)
	local_irq_save(flags);
	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
	if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS) {
	if (!hv_result_success(status)) {
		/* No point in proceeding if this failed */
		pr_err("Failed to get partition ID: %lld\n", status);
		BUG();
+10 −15
Original line number Diff line number Diff line
@@ -92,10 +92,9 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
	status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
				     page_count, 0, input_page, NULL);
	local_irq_restore(flags);

	if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS) {
	if (!hv_result_success(status)) {
		pr_err("Failed to deposit pages: %lld\n", status);
		ret = status;
		ret = hv_result(status);
		goto err_free_allocations;
	}

@@ -121,7 +120,7 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
	struct hv_add_logical_processor_out *output;
	u64 status;
	unsigned long flags;
	int ret = 0;
	int ret = HV_STATUS_SUCCESS;
	int pxm = node_to_pxm(node);

	/*
@@ -147,13 +146,11 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
					 input, output);
		local_irq_restore(flags);

		status &= HV_HYPERCALL_RESULT_MASK;

		if (status != HV_STATUS_INSUFFICIENT_MEMORY) {
			if (status != HV_STATUS_SUCCESS) {
		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
			if (!hv_result_success(status)) {
				pr_err("%s: cpu %u apic ID %u, %lld\n", __func__,
				       lp_index, apic_id, status);
				ret = status;
				ret = hv_result(status);
			}
			break;
		}
@@ -168,7 +165,7 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
	struct hv_create_vp *input;
	u64 status;
	unsigned long irq_flags;
	int ret = 0;
	int ret = HV_STATUS_SUCCESS;
	int pxm = node_to_pxm(node);

	/* Root VPs don't seem to need pages deposited */
@@ -199,13 +196,11 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
		status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
		local_irq_restore(irq_flags);

		status &= HV_HYPERCALL_RESULT_MASK;

		if (status != HV_STATUS_INSUFFICIENT_MEMORY) {
			if (status != HV_STATUS_SUCCESS) {
		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
			if (!hv_result_success(status)) {
				pr_err("%s: vcpu %u, lp %u, %lld\n", __func__,
				       vp_index, flags, status);
				ret = status;
				ret = hv_result(status);
			}
			break;
		}
+3 −3
Original line number Diff line number Diff line
@@ -63,10 +63,10 @@ static int hv_map_interrupt(union hv_device_id device_id, bool level,

	local_irq_restore(flags);

	if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
	if (!hv_result_success(status))
		pr_err("%s: hypercall failed, status %lld\n", __func__, status);

	return status & HV_HYPERCALL_RESULT_MASK;
	return hv_result(status);
}

static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
@@ -88,7 +88,7 @@ static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
	status = hv_do_hypercall(HVCALL_UNMAP_DEVICE_INTERRUPT, input, NULL);
	local_irq_restore(flags);

	return status & HV_HYPERCALL_RESULT_MASK;
	return hv_result(status);
}

#ifdef CONFIG_PCI_MSI
+4 −4
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
	int cpu, vcpu, gva_n, max_gvas;
	struct hv_tlb_flush **flush_pcpu;
	struct hv_tlb_flush *flush;
	u64 status = U64_MAX;
	u64 status;
	unsigned long flags;

	trace_hyperv_mmu_flush_tlb_others(cpus, info);
@@ -161,7 +161,7 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
check_status:
	local_irq_restore(flags);

	if (!(status & HV_HYPERCALL_RESULT_MASK))
	if (hv_result_success(status))
		return;
do_native:
	native_flush_tlb_others(cpus, info);
@@ -176,7 +176,7 @@ static u64 hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
	u64 status;

	if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
		return U64_MAX;
		return HV_STATUS_INVALID_PARAMETER;

	flush_pcpu = (struct hv_tlb_flush_ex **)
		     this_cpu_ptr(hyperv_pcpu_input_arg);
@@ -201,7 +201,7 @@ static u64 hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
	flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
	nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
	if (nr_bank < 0)
		return U64_MAX;
		return HV_STATUS_INVALID_PARAMETER;

	/*
	 * We can flush not more than max_gvas with one hypercall. Flush the
Loading