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
......@@ -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:
......
......@@ -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;
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment