Commit 59aeea19 authored by Purna Pavan Chandra Aekkaladevi's avatar Purna Pavan Chandra Aekkaladevi Committed by Wei Liu
Browse files

mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall



This hypercall can be used to fetch extended properties of a
partition. Extended properties are properties with values larger than
a u64. Some of these also need additional input arguments.

Add helper function for using the hypercall in the mshv_root driver.

Signed-off-by: default avatarPurna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Signed-off-by: default avatarNuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: default avatarAnirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: default avatarPraveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: default avatarEaswar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: default avatarTianyu Lan <tiala@microsoft.com>
Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent 9ebc528c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -303,6 +303,8 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type type,
int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
				   u64 page_struct_count, u32 host_access,
				   u32 flags, u8 acquire);
int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code, u64 arg,
				      void *property_value, size_t property_value_sz);

extern struct mshv_root mshv_root;
extern enum hv_scheduler_type hv_scheduler_type;
+31 −0
Original line number Diff line number Diff line
@@ -590,6 +590,37 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
	return hv_result_to_errno(status);
}

int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
				      u64 arg, void *property_value,
				      size_t property_value_sz)
{
	u64 status;
	unsigned long flags;
	struct hv_input_get_partition_property_ex *input;
	struct hv_output_get_partition_property_ex *output;

	local_irq_save(flags);
	input = *this_cpu_ptr(hyperv_pcpu_input_arg);
	output = *this_cpu_ptr(hyperv_pcpu_output_arg);

	memset(input, 0, sizeof(*input));
	input->partition_id = partition_id;
	input->property_code = property_code;
	input->arg = arg;
	status = hv_do_hypercall(HVCALL_GET_PARTITION_PROPERTY_EX, input, output);

	if (!hv_result_success(status)) {
		local_irq_restore(flags);
		hv_status_debug(status, "\n");
		return hv_result_to_errno(status);
	}
	memcpy(property_value, &output->property_value, property_value_sz);

	local_irq_restore(flags);

	return 0;
}

int
hv_call_clear_virtual_interrupt(u64 partition_id)
{
+1 −0
Original line number Diff line number Diff line
@@ -491,6 +491,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_STATE				0x00e3
#define HVCALL_SET_VP_STATE				0x00e4
#define HVCALL_GET_VP_CPUID_VALUES			0x00f4
#define HVCALL_GET_PARTITION_PROPERTY_EX		0x0101
#define HVCALL_MMIO_READ				0x0106
#define HVCALL_MMIO_WRITE				0x0107

+40 −0
Original line number Diff line number Diff line
@@ -376,6 +376,46 @@ struct hv_input_set_partition_property {
	u64 property_value;
} __packed;

union hv_partition_property_arg {
	u64 as_uint64;
	struct {
		union {
			u32 arg;
			u32 vp_index;
		};
		u16 reserved0;
		u8 reserved1;
		u8 object_type;
	} __packed;
};

struct hv_input_get_partition_property_ex {
	u64 partition_id;
	u32 property_code; /* enum hv_partition_property_code */
	u32 padding;
	union {
		union hv_partition_property_arg arg_data;
		u64 arg;
	};
} __packed;

/*
 * NOTE: Should use hv_input_set_partition_property_ex_header to compute this
 * size, but hv_input_get_partition_property_ex is identical so it suffices
 */
#define HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE \
	(HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_partition_property_ex))

union hv_partition_property_ex {
	u8 buffer[HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE];
	struct hv_partition_property_vmm_capabilities vmm_capabilities;
	/* More fields to be filled in when needed */
};

struct hv_output_get_partition_property_ex {
	union hv_partition_property_ex property_value;
} __packed;

enum hv_vp_state_page_type {
	HV_VP_STATE_PAGE_REGISTERS = 0,
	HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
+26 −0
Original line number Diff line number Diff line
@@ -96,8 +96,34 @@ enum hv_partition_property_code {
	HV_PARTITION_PROPERTY_XSAVE_STATES                      = 0x00060007,
	HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE		= 0x00060008,
	HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY		= 0x00060009,

	/* Extended properties with larger property values */
	HV_PARTITION_PROPERTY_VMM_CAPABILITIES			= 0x00090007,
};

#define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT		1
#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT	59

struct hv_partition_property_vmm_capabilities {
	u16 bank_count;
	u16 reserved[3];
	union {
		u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
		struct {
			u64 map_gpa_preserve_adjustable: 1;
			u64 vmm_can_provide_overlay_gpfn: 1;
			u64 vp_affinity_property: 1;
#if IS_ENABLED(CONFIG_ARM64)
			u64 vmm_can_provide_gic_overlay_locations: 1;
#else
			u64 reservedbit3: 1;
#endif
			u64 assignable_synthetic_proc_features: 1;
			u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
		} __packed;
	};
} __packed;

enum hv_snp_status {
	HV_SNP_STATUS_NONE = 0,
	HV_SNP_STATUS_AVAILABLE = 1,