Skip to content

Commit

Permalink
x86/hyper-v: Mark TLFS structures packed
Browse files Browse the repository at this point in the history
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@gmail.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Vitaly Kuznetsov authored and Paolo Bonzini committed Dec 14, 2018
1 parent 7deec5e commit ec08449
Showing 1 changed file with 25 additions and 22 deletions.
47 changes: 25 additions & 22 deletions arch/x86/include/asm/hyperv-tlfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ union hv_x64_msr_hypercall_contents {
u64 enable:1;
u64 reserved:11;
u64 guest_physical_address:52;
};
} __packed;
};

/*
Expand All @@ -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.
Expand Down Expand Up @@ -324,20 +324,20 @@ 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

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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -466,7 +466,7 @@ union hv_message_flags {
struct {
__u8 msg_pending:1;
__u8 reserved:7;
};
} __packed;
};

/* Define port identifier type. */
Expand All @@ -475,7 +475,7 @@ union hv_port_id {
struct {
__u32 id:24;
__u32 reserved:8;
} u;
} __packed u;
};

/* Define synthetic interrupt controller message header. */
Expand All @@ -488,28 +488,28 @@ struct hv_message_header {
__u64 sender;
union hv_port_id port;
};
};
} __packed;

/* Define synthetic interrupt controller message format. */
struct hv_message {
struct hv_message_header header;
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 {
__u32 timer_index;
__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 {
Expand All @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -735,42 +738,42 @@ 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 {
u64 address_space;
u64 flags;
u64 processor_mask;
u64 gva_list[];
};
} __packed;

/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
struct hv_tlb_flush_ex {
u64 address_space;
u64 flags;
struct hv_vpset hv_vp_set;
u64 gva_list[];
};
} __packed;

#endif

0 comments on commit ec08449

Please sign in to comment.