Commit 99a0f46a authored by Wei Liu's avatar Wei Liu
Browse files

x86/hyperv: extract partition ID from Microsoft Hypervisor if necessary



We will need the partition ID for executing some hypercalls later.

Signed-off-by: default avatarLillian Grassin-Drake <ligrassi@microsoft.com>
Co-Developed-by: default avatarSunil Muthuswamy <sunilmut@microsoft.com>
Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/20210203150435.27941-7-wei.liu@kernel.org
parent 5d0f077e
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
#include <clocksource/hyperv_timer.h>

int hyperv_init_cpuhp;
u64 hv_current_partition_id = ~0ull;
EXPORT_SYMBOL_GPL(hv_current_partition_id);

void *hv_hypercall_pg;
EXPORT_SYMBOL_GPL(hv_hypercall_pg);
@@ -354,6 +356,24 @@ static void __init hv_stimer_setup_percpu_clockev(void)
		old_setup_percpu_clockev();
}

static void __init hv_get_partition_id(void)
{
	struct hv_get_partition_id *output_page;
	u64 status;
	unsigned long flags;

	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) {
		/* No point in proceeding if this failed */
		pr_err("Failed to get partition ID: %lld\n", status);
		BUG();
	}
	hv_current_partition_id = output_page->partition_id;
	local_irq_restore(flags);
}

/*
 * This function is to be invoked early in the boot sequence after the
 * hypervisor has been detected.
@@ -454,6 +474,12 @@ void __init hyperv_init(void)
	register_syscore_ops(&hv_syscore_ops);

	hyperv_init_cpuhp = cpuhp;

	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
		hv_get_partition_id();

	BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);

	return;

remove_cpuhp_state:
+2 −0
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ extern void *hv_hypercall_pg;
extern void  __percpu  **hyperv_pcpu_input_arg;
extern void  __percpu  **hyperv_pcpu_output_arg;

extern u64 hv_current_partition_id;

static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
{
	u64 input_address = input ? virt_to_phys(input) : 0;
+6 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ struct ms_hyperv_tsc_page {
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX	0x0013
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX	0x0014
#define HVCALL_SEND_IPI_EX			0x0015
#define HVCALL_GET_PARTITION_ID			0x0046
#define HVCALL_GET_VP_REGISTERS			0x0050
#define HVCALL_SET_VP_REGISTERS			0x0051
#define HVCALL_POST_MESSAGE			0x005c
@@ -408,6 +409,11 @@ struct hv_tlb_flush_ex {
	u64 gva_list[];
} __packed;

/* HvGetPartitionId hypercall (output only) */
struct hv_get_partition_id {
	u64 partition_id;
} __packed;

/* HvRetargetDeviceInterrupt hypercall */
union hv_msi_entry {
	u64 as_uint64;