[PATCH v3 1/5] hyperv: Define struct hv_output_get_vp_registers

Roman Kisel posted 5 patches 1 year, 1 month ago
There is a newer version of this series
[PATCH v3 1/5] hyperv: Define struct hv_output_get_vp_registers
Posted by Roman Kisel 1 year, 1 month ago
There is no definition of the output structure for the
GetVpRegisters hypercall. Hence, using the hypercall
is not possible when the output value has some structure
to it. Even getting a datum of a primitive type reads
as ad-hoc without that definition.

Define struct hv_output_get_vp_registers to enable using
the GetVpRegisters hypercall. Make provisions for all
supported architectures. No functional changes.

Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
---
 include/hyperv/hvgdk_mini.h | 58 +++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index db3d1aaf7330..31c11550af73 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -781,6 +781,8 @@ struct hv_timer_message_payload {
 	__u64 delivery_time;	/* When the message was delivered */
 } __packed;
 
+#if defined(CONFIG_X86)
+
 struct hv_x64_segment_register {
 	u64 base;
 	u32 limit;
@@ -807,6 +809,8 @@ struct hv_x64_table_register {
 	u64 base;
 } __packed;
 
+#endif
+
 union hv_input_vtl {
 	u8 as_uint8;
 	struct {
@@ -1068,6 +1072,41 @@ union hv_dispatch_suspend_register {
 	} __packed;
 };
 
+#if defined(CONFIG_ARM64)
+
+union hv_arm64_pending_interruption_register {
+	u64 as_uint64;
+	struct {
+		u64 interruption_pending : 1;
+		u64 interruption_type : 1;
+		u64 reserved : 30;
+		u32 error_code;
+	} __packed;
+};
+
+union hv_arm64_interrupt_state_register {
+	u64 as_uint64;
+	struct {
+		u64 interrupt_shadow : 1;
+		u64 reserved : 63;
+	} __packed;
+};
+
+union hv_arm64_pending_synthetic_exception_event {
+	u64 as_uint64[2];
+	struct {
+		u32 event_pending : 1;
+		u32 event_type : 3;
+		u32 reserved : 4;
+		u32 exception_type;
+		u64 context;
+	} __packed;
+};
+
+#endif
+
+#if defined(CONFIG_X86)
+
 union hv_x64_interrupt_state_register {
 	u64 as_uint64;
 	struct {
@@ -1091,6 +1130,8 @@ union hv_x64_pending_interruption_register {
 	} __packed;
 };
 
+#endif
+
 union hv_register_value {
 	struct hv_u128 reg128;
 	u64 reg64;
@@ -1098,13 +1139,26 @@ union hv_register_value {
 	u16 reg16;
 	u8 reg8;
 
-	struct hv_x64_segment_register segment;
-	struct hv_x64_table_register table;
 	union hv_explicit_suspend_register explicit_suspend;
 	union hv_intercept_suspend_register intercept_suspend;
 	union hv_dispatch_suspend_register dispatch_suspend;
+#if defined(CONFIG_X86)
+	struct hv_x64_segment_register segment;
+	struct hv_x64_table_register table;
 	union hv_x64_interrupt_state_register interrupt_state;
 	union hv_x64_pending_interruption_register pending_interruption;
+#elif defined(CONFIG_ARM64)
+	union hv_arm64_pending_interruption_register pending_interruption;
+	union hv_arm64_interrupt_state_register interrupt_state;
+	union hv_arm64_pending_synthetic_exception_event pending_synthetic_exception_event;
+#else
+	#error "This architecture is not supported"
+#endif
+};
+
+/* NOTE: Linux helper struct - NOT from Hyper-V code */
+struct hv_output_get_vp_registers {
+	DECLARE_FLEX_ARRAY(union hv_register_value, values);
 };
 
 #if defined(CONFIG_ARM64)
-- 
2.34.1
Re: [PATCH v3 1/5] hyperv: Define struct hv_output_get_vp_registers
Posted by Easwar Hariharan 1 year, 1 month ago
On 12/26/2024 1:31 PM, Roman Kisel wrote:
> There is no definition of the output structure for the
> GetVpRegisters hypercall. Hence, using the hypercall
> is not possible when the output value has some structure
> to it. Even getting a datum of a primitive type reads
> as ad-hoc without that definition.
> 
> Define struct hv_output_get_vp_registers to enable using
> the GetVpRegisters hypercall. Make provisions for all
> supported architectures. No functional changes.
> 
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> ---
>  include/hyperv/hvgdk_mini.h | 58 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 56 insertions(+), 2 deletions(-)
> 
>  	struct {
> @@ -1091,6 +1130,8 @@ union hv_x64_pending_interruption_register {
>  	} __packed;
>  };
>  
> +#endif
> +
>  union hv_register_value {
>  	struct hv_u128 reg128;
>  	u64 reg64;
> @@ -1098,13 +1139,26 @@ union hv_register_value {
>  	u16 reg16;
>  	u8 reg8;
>  
> -	struct hv_x64_segment_register segment;
> -	struct hv_x64_table_register table;
>  	union hv_explicit_suspend_register explicit_suspend;
>  	union hv_intercept_suspend_register intercept_suspend;
>  	union hv_dispatch_suspend_register dispatch_suspend;
> +#if defined(CONFIG_X86)
> +	struct hv_x64_segment_register segment;
> +	struct hv_x64_table_register table;
>  	union hv_x64_interrupt_state_register interrupt_state;
>  	union hv_x64_pending_interruption_register pending_interruption;
> +#elif defined(CONFIG_ARM64)
> +	union hv_arm64_pending_interruption_register pending_interruption;
> +	union hv_arm64_interrupt_state_register interrupt_state;
> +	union hv_arm64_pending_synthetic_exception_event pending_synthetic_exception_event;
> +#else
> +	#error "This architecture is not supported"
> +#endif
> +};

I don't love the #error for unsupported architectures when Kconfig takes
care of that for us, but I suppose it's for completeness since the arm64
members have to be conditioned on CONFIG_ARM64?

> +
> +/* NOTE: Linux helper struct - NOT from Hyper-V code */
> +struct hv_output_get_vp_registers {
> +	DECLARE_FLEX_ARRAY(union hv_register_value, values);
>  };

I'm not super familiar with DECLARE_FLEX_ARRAY() but it appears this
needs to be wrapped in an anonymous struct at the least per this comment
for the definition of DECLARE_FLEX_ARRAY()

> * In order to have a flexible array member [...] alone in a
> * struct, it needs to be wrapped in an anonymous struct with at least 1
> * named member, but that member can be empty.

Nuno, since you seem to be more familiar, can you provide some guidance?

Thanks,
Easwar
Re: [PATCH v3 1/5] hyperv: Define struct hv_output_get_vp_registers
Posted by Roman Kisel 1 year, 1 month ago

On 12/26/2024 2:11 PM, Easwar Hariharan wrote:
> On 12/26/2024 1:31 PM, Roman Kisel wrote:

[...]

>> +#else
>> +	#error "This architecture is not supported"
>> +#endif
>> +};
> 
> I don't love the #error for unsupported architectures when Kconfig takes
> care of that for us, but I suppose it's for completeness since the arm64
> members have to be conditioned on CONFIG_ARM64?
> 
Felt right to do that, but because it raises questions, it should carry
a comment or be removed as, if you pointed out, Kconfig is in charge of
that kind of validation. As Kconfig permits Hyper-V on the correct set
of arch'es, the best choice would be to remove I think.

>> +
>> +/* NOTE: Linux helper struct - NOT from Hyper-V code */
>> +struct hv_output_get_vp_registers {
>> +	DECLARE_FLEX_ARRAY(union hv_register_value, values);
>>   };
> 
> I'm not super familiar with DECLARE_FLEX_ARRAY() but it appears this
> needs to be wrapped in an anonymous struct at the least per this comment
> for the definition of DECLARE_FLEX_ARRAY()
> 
>> * In order to have a flexible array member [...] alone in a
>> * struct, it needs to be wrapped in an anonymous struct with at least 1
>> * named member, but that member can be empty.
> 
> Nuno, since you seem to be more familiar, can you provide some guidance?
I will wrap the struct member of the documentation requires, not to
make the code look suspicious.

> 
> Thanks,
> Easwar

-- 
Thank you,
Roman