Re: [PATCH v4] x86/hyper-v: Mark TLFS structures packed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/12/18 18:57, Vitaly Kuznetsov wrote:
> The TLFS structures are used for hypervisor-guest communication and must
> exactly meet the specification.
> 
> Compilers can add alignment padding to structures or reorder struct members
> for randomization and optimization, which would break the hypervisor ABI.
> 
> Mark the structures as packed to prevent this. 'struct hv_vp_assist_page'
> and 'struct hv_enlightened_vmcs' need to be properly padded to support the
> change.
> 
> Suggested-by: Nadav Amit <nadav.amit@xxxxxxxxx>
> Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx>
> Acked-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Acked-by: Nadav Amit <nadav.amit@xxxxxxxxx>
> Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>
> ---
> - Changes since v3:
>  - Properly pad 'struct hv_vp_assist_page' and 'struct hv_enlightened_vmcs'.
>  - Add Michael's Reviewed-by tag.
> 
> - This is a follow-up to my "[PATCH v2 0/4] x86/kvm/hyper-v: Implement
>  Direct Mode for synthetic timers" series, as suggested by Thomas I'm
>  routing it to KVM tree to avoid merge conflicts.
> ---
>  arch/x86/include/asm/hyperv-tlfs.h | 57 ++++++++++++++++--------------
>  1 file changed, 30 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
> index ebfed56976d2..64d2b1914d37 100644
> --- a/arch/x86/include/asm/hyperv-tlfs.h
> +++ b/arch/x86/include/asm/hyperv-tlfs.h
> @@ -271,7 +271,7 @@ union hv_x64_msr_hypercall_contents {
>  		u64 enable:1;
>  		u64 reserved:11;
>  		u64 guest_physical_address:52;
> -	};
> +	} __packed;
>  };
>  
>  /*
> @@ -283,7 +283,7 @@ struct ms_hyperv_tsc_page {
>  	volatile u64 tsc_scale;
>  	volatile s64 tsc_offset;
>  	u64 reserved2[509];
> -};
> +}  __packed;
>  
>  /*
>   * The guest OS needs to register the guest ID with the hypervisor.
> @@ -324,7 +324,7 @@ struct hv_reenlightenment_control {
>  	__u64 enabled:1;
>  	__u64 reserved2:15;
>  	__u64 target_vp:32;
> -};
> +}  __packed;
>  
>  #define HV_X64_MSR_TSC_EMULATION_CONTROL	0x40000107
>  #define HV_X64_MSR_TSC_EMULATION_STATUS		0x40000108
> @@ -332,12 +332,12 @@ struct hv_reenlightenment_control {
>  struct hv_tsc_emulation_control {
>  	__u64 enabled:1;
>  	__u64 reserved:63;
> -};
> +} __packed;
>  
>  struct hv_tsc_emulation_status {
>  	__u64 inprogress:1;
>  	__u64 reserved:63;
> -};
> +} __packed;
>  
>  #define HV_X64_MSR_HYPERCALL_ENABLE		0x00000001
>  #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT	12
> @@ -409,7 +409,7 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
>  	__u32 res1;
>  	__u64 tsc_scale;
>  	__s64 tsc_offset;
> -} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
> +}  __packed HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
>  
>  /* Define the number of synthetic interrupt sources. */
>  #define HV_SYNIC_SINT_COUNT		(16)
> @@ -466,7 +466,7 @@ union hv_message_flags {
>  	struct {
>  		__u8 msg_pending:1;
>  		__u8 reserved:7;
> -	};
> +	} __packed;
>  };
>  
>  /* Define port identifier type. */
> @@ -475,7 +475,7 @@ union hv_port_id {
>  	struct {
>  		__u32 id:24;
>  		__u32 reserved:8;
> -	} u;
> +	} __packed u;
>  };
>  
>  /* Define synthetic interrupt controller message header. */
> @@ -488,7 +488,7 @@ struct hv_message_header {
>  		__u64 sender;
>  		union hv_port_id port;
>  	};
> -};
> +} __packed;
>  
>  /* Define synthetic interrupt controller message format. */
>  struct hv_message {
> @@ -496,12 +496,12 @@ struct hv_message {
>  	union {
>  		__u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
>  	} u;
> -};
> +} __packed;
>  
>  /* Define the synthetic interrupt message page layout. */
>  struct hv_message_page {
>  	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
> -};
> +} __packed;
>  
>  /* Define timer message payload structure. */
>  struct hv_timer_message_payload {
> @@ -509,7 +509,7 @@ struct hv_timer_message_payload {
>  	__u32 reserved;
>  	__u64 expiration_time;	/* When the timer expired */
>  	__u64 delivery_time;	/* When the message was delivered */
> -};
> +} __packed;
>  
>  /* Define virtual processor assist page structure. */
>  struct hv_vp_assist_page {
> @@ -518,8 +518,9 @@ struct hv_vp_assist_page {
>  	__u64 vtl_control[2];
>  	__u64 nested_enlightenments_control[2];
>  	__u32 enlighten_vmentry;
> +	__u32 padding;
>  	__u64 current_nested_vmcs;
> -};
> +} __packed;
>  
>  struct hv_enlightened_vmcs {
>  	u32 revision_id;
> @@ -533,6 +534,8 @@ struct hv_enlightened_vmcs {
>  	u16 host_gs_selector;
>  	u16 host_tr_selector;
>  
> +	u16 padding16_1;
> +
>  	u64 host_ia32_pat;
>  	u64 host_ia32_efer;
>  
> @@ -651,7 +654,7 @@ struct hv_enlightened_vmcs {
>  	u64 ept_pointer;
>  
>  	u16 virtual_processor_id;
> -	u16 padding16[3];
> +	u16 padding16_2[3];
>  
>  	u64 padding64_2[5];
>  	u64 guest_physical_address;
> @@ -693,7 +696,7 @@ struct hv_enlightened_vmcs {
>  		u32 nested_flush_hypercall:1;
>  		u32 msr_bitmap:1;
>  		u32 reserved:30;
> -	} hv_enlightenments_control;
> +	}  __packed hv_enlightenments_control;
>  	u32 hv_vp_id;
>  
>  	u64 hv_vm_id;
> @@ -703,7 +706,7 @@ struct hv_enlightened_vmcs {
>  	u64 padding64_5[7];
>  	u64 xss_exit_bitmap;
>  	u64 padding64_6[7];
> -};
> +} __packed;
>  
>  #define HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE			0
>  #define HV_VMX_ENLIGHTENED_CLEAN_FIELD_IO_BITMAP		BIT(0)
> @@ -744,7 +747,7 @@ union hv_stimer_config {
>  		u64 reserved_z0:3;
>  		u64 sintx:4;
>  		u64 reserved_z1:44;
> -	};
> +	} __packed;
>  };
>  
>  
> @@ -759,7 +762,7 @@ union hv_synic_scontrol {
>  	struct {
>  		u64 enable:1;
>  		u64 reserved:63;
> -	};
> +	} __packed;
>  };
>  
>  /* Define synthetic interrupt source. */
> @@ -771,7 +774,7 @@ union hv_synic_sint {
>  		u64 masked:1;
>  		u64 auto_eoi:1;
>  		u64 reserved2:46;
> -	};
> +	} __packed;
>  };
>  
>  /* Define the format of the SIMP register */
> @@ -781,7 +784,7 @@ union hv_synic_simp {
>  		u64 simp_enabled:1;
>  		u64 preserved:11;
>  		u64 base_simp_gpa:52;
> -	};
> +	} __packed;
>  };
>  
>  /* Define the format of the SIEFP register */
> @@ -791,34 +794,34 @@ union hv_synic_siefp {
>  		u64 siefp_enabled:1;
>  		u64 preserved:11;
>  		u64 base_siefp_gpa:52;
> -	};
> +	} __packed;
>  };
>  
>  struct hv_vpset {
>  	u64 format;
>  	u64 valid_bank_mask;
>  	u64 bank_contents[];
> -};
> +} __packed;
>  
>  /* HvCallSendSyntheticClusterIpi hypercall */
>  struct hv_send_ipi {
>  	u32 vector;
>  	u32 reserved;
>  	u64 cpu_mask;
> -};
> +} __packed;
>  
>  /* HvCallSendSyntheticClusterIpiEx hypercall */
>  struct hv_send_ipi_ex {
>  	u32 vector;
>  	u32 reserved;
>  	struct hv_vpset vp_set;
> -};
> +} __packed;
>  
>  /* HvFlushGuestPhysicalAddressSpace hypercalls */
>  struct hv_guest_mapping_flush {
>  	u64 address_space;
>  	u64 flags;
> -};
> +} __packed;
>  
>  /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
>  struct hv_tlb_flush {
> @@ -826,7 +829,7 @@ struct hv_tlb_flush {
>  	u64 flags;
>  	u64 processor_mask;
>  	u64 gva_list[];
> -};
> +} __packed;
>  
>  /* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
>  struct hv_tlb_flush_ex {
> @@ -834,6 +837,6 @@ struct hv_tlb_flush_ex {
>  	u64 flags;
>  	struct hv_vpset hv_vp_set;
>  	u64 gva_list[];
> -};
> +} __packed;
>  
>  #endif
> 

Queued, thanks.  I squashed the SynIC parts into "x86/hyper-v: move
synic/stimer control structures definitions to hyperv-tlfs.h" and kept
the rest separate.

Paolo



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux