diff mbox

[v3,1/3] SMBIOS: Fix endian-ness when populating fields wider than 8-bit

Message ID 1400015769-717-2-git-send-email-somlo@cmu.edu
State New
Headers show

Commit Message

Gabriel L. Somlo May 13, 2014, 9:16 p.m. UTC
When i386 guests are emulated on big endian hosts, make sure
fields wider than 8 bits are populated safely via cpu_to_le*().

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
---
 hw/i386/smbios.c | 92 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 47 insertions(+), 45 deletions(-)

Comments

Michael S. Tsirkin May 19, 2014, 10:53 a.m. UTC | #1
On Tue, May 13, 2014 at 05:16:07PM -0400, Gabriel L. Somlo wrote:
> When i386 guests are emulated on big endian hosts, make sure
> fields wider than 8 bits are populated safely via cpu_to_le*().
> 
> Signed-off-by: Gabriel Somlo <somlo@cmu.edu>

Reviewed-by: Michael S. Tsirkin <mst@redhat.com>

> ---
>  hw/i386/smbios.c | 92 +++++++++++++++++++++++++++++---------------------------
>  1 file changed, 47 insertions(+), 45 deletions(-)
> 
> diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
> index 7660718..aeb94bc 100644
> --- a/hw/i386/smbios.c
> +++ b/hw/i386/smbios.c
> @@ -444,7 +444,7 @@ static bool smbios_skip_table(uint8_t type, bool required_table)
>                                                                            \
>          t->header.type = tbl_type;                                        \
>          t->header.length = sizeof(*t);                                    \
> -        t->header.handle = tbl_handle;                                    \
> +        t->header.handle = cpu_to_le16(tbl_handle);                       \
>      } while (0)
>  
>  #define SMBIOS_TABLE_SET_STR(tbl_type, field, value)                      \
> @@ -491,7 +491,7 @@ static void smbios_build_type_0_table(void)
>      SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
>      SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
>  
> -    t->bios_starting_address_segment = 0xE800; /* hardcoded in SeaBIOS */
> +    t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
>  
>      SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
>  
> @@ -551,7 +551,7 @@ static void smbios_build_type_2_table(void)
>      SMBIOS_TABLE_SET_STR(2, asset_tag_number_str, type2.asset);
>      t->feature_flags = 0x01; /* Motherboard */
>      SMBIOS_TABLE_SET_STR(2, location_str, type2.location);
> -    t->chassis_handle = 0x300; /* Type 3 (System enclosure) */
> +    t->chassis_handle = cpu_to_le16(0x300); /* Type 3 (System enclosure) */
>      t->board_type = 0x0A; /* Motherboard */
>      t->contained_element_count = 0;
>  
> @@ -571,7 +571,7 @@ static void smbios_build_type_3_table(void)
>      t->power_supply_state = 0x03; /* Safe */
>      t->thermal_state = 0x03; /* Safe */
>      t->security_status = 0x02; /* Unknown */
> -    t->oem_defined = 0;
> +    t->oem_defined = cpu_to_le32(0);
>      t->height = 0;
>      t->number_of_power_cords = 0;
>      t->contained_element_count = 0;
> @@ -589,26 +589,27 @@ static void smbios_build_type_4_table(unsigned instance)
>      snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
>      SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
>      t->processor_type = 0x03; /* CPU */
> +    t->processor_family = 0x01; /* Other */
>      SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer);
> -    t->processor_id[0] = smbios_cpuid_version;
> -    t->processor_id[1] = smbios_cpuid_features;
> +    t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
> +    t->processor_id[1] = cpu_to_le32(smbios_cpuid_features);
>      SMBIOS_TABLE_SET_STR(4, processor_version_str, type4.version);
>      t->voltage = 0;
> -    t->external_clock = 0; /* Unknown */
> -    t->max_speed = 0; /* Unknown */
> -    t->current_speed = 0; /* Unknown */
> +    t->external_clock = cpu_to_le16(0); /* Unknown */
> +    t->max_speed = cpu_to_le16(0); /* Unknown */
> +    t->current_speed = cpu_to_le16(0); /* Unknown */
>      t->status = 0x41; /* Socket populated, CPU enabled */
>      t->processor_upgrade = 0x01; /* Other */
> -    t->l1_cache_handle = 0xFFFF; /* N/A */
> -    t->l2_cache_handle = 0xFFFF; /* N/A */
> -    t->l3_cache_handle = 0xFFFF; /* N/A */
> +    t->l1_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
> +    t->l2_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
> +    t->l3_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
>      SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
>      SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
>      SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
>      t->core_count = t->core_enabled = smp_cores;
>      t->thread_count = smp_threads;
> -    t->processor_characteristics = 0x02; /* Unknown */
> -    t->processor_family = t->processor_family2 = 0x01; /* Other */
> +    t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
> +    t->processor_family2 = cpu_to_le16(0x01); /* Other */
>  
>      SMBIOS_BUILD_TABLE_POST;
>      smbios_type4_count++;
> @@ -631,14 +632,14 @@ static void smbios_build_type_16_table(unsigned dimm_cnt)
>      t->error_correction = 0x06; /* Multi-bit ECC (for Microsoft, per SeaBIOS) */
>      size_kb = QEMU_ALIGN_UP(ram_size, ONE_KB) / ONE_KB;
>      if (size_kb < MAX_T16_STD_SZ) {
> -        t->maximum_capacity = size_kb;
> -        t->extended_maximum_capacity = 0;
> +        t->maximum_capacity = cpu_to_le32(size_kb);
> +        t->extended_maximum_capacity = cpu_to_le64(0);
>      } else {
> -        t->maximum_capacity = MAX_T16_STD_SZ;
> -        t->extended_maximum_capacity = ram_size;
> +        t->maximum_capacity = cpu_to_le32(MAX_T16_STD_SZ);
> +        t->extended_maximum_capacity = cpu_to_le64(ram_size);
>      }
> -    t->memory_error_information_handle = 0xFFFE; /* Not provided */
> -    t->number_of_memory_devices = dimm_cnt;
> +    t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
> +    t->number_of_memory_devices = cpu_to_le16(dimm_cnt);
>  
>      SMBIOS_BUILD_TABLE_POST;
>  }
> @@ -653,18 +654,18 @@ static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
>  
>      SMBIOS_BUILD_TABLE_PRE(17, 0x1100 + instance, true); /* required */
>  
> -    t->physical_memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
> -    t->memory_error_information_handle = 0xFFFE; /* Not provided */
> -    t->total_width = 0xFFFF; /* Unknown */
> -    t->data_width = 0xFFFF; /* Unknown */
> +    t->physical_memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
> +    t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
> +    t->total_width = cpu_to_le16(0xFFFF); /* Unknown */
> +    t->data_width = cpu_to_le16(0xFFFF); /* Unknown */
>      size_mb = QEMU_ALIGN_UP(size, ONE_MB) / ONE_MB;
>      if (size_mb < MAX_T17_STD_SZ) {
> -        t->size = size_mb;
> -        t->extended_size = 0;
> +        t->size = cpu_to_le16(size_mb);
> +        t->extended_size = cpu_to_le32(0);
>      } else {
>          assert(size_mb < MAX_T17_EXT_SZ);
> -        t->size = MAX_T17_STD_SZ;
> -        t->extended_size = size_mb;
> +        t->size = cpu_to_le16(MAX_T17_STD_SZ);
> +        t->extended_size = cpu_to_le32(size_mb);
>      }
>      t->form_factor = 0x09; /* DIMM */
>      t->device_set = 0; /* Not in a set */
> @@ -672,17 +673,17 @@ static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
>      SMBIOS_TABLE_SET_STR(17, device_locator_str, loc_str);
>      SMBIOS_TABLE_SET_STR(17, bank_locator_str, type17.bank);
>      t->memory_type = 0x07; /* RAM */
> -    t->type_detail = 0x02; /* Other */
> -    t->speed = 0; /* Unknown */
> +    t->type_detail = cpu_to_le16(0x02); /* Other */
> +    t->speed = cpu_to_le16(0); /* Unknown */
>      SMBIOS_TABLE_SET_STR(17, manufacturer_str, type17.manufacturer);
>      SMBIOS_TABLE_SET_STR(17, serial_number_str, type17.serial);
>      SMBIOS_TABLE_SET_STR(17, asset_tag_number_str, type17.asset);
>      SMBIOS_TABLE_SET_STR(17, part_number_str, type17.part);
>      t->attributes = 0; /* Unknown */
> -    t->configured_clock_speed = 0; /* Unknown */
> -    t->minimum_voltage = 0; /* Unknown */
> -    t->maximum_voltage = 0; /* Unknown */
> -    t->configured_voltage = 0; /* Unknown */
> +    t->configured_clock_speed = cpu_to_le32(0); /* Unknown */
> +    t->minimum_voltage = cpu_to_le32(0); /* Unknown */
> +    t->maximum_voltage = cpu_to_le32(0); /* Unknown */
> +    t->configured_voltage = cpu_to_le32(0); /* Unknown */
>  
>      SMBIOS_BUILD_TABLE_POST;
>  }
> @@ -699,15 +700,16 @@ static void smbios_build_type_19_table(unsigned instance,
>      start_kb = start / ONE_KB;
>      end_kb = end / ONE_KB;
>      if (start_kb < UINT32_MAX && end_kb < UINT32_MAX) {
> -        t->starting_address = start_kb;
> -        t->ending_address = end_kb;
> -        t->extended_starting_address = t->extended_ending_address = 0;
> +        t->starting_address = cpu_to_le32(start_kb);
> +        t->ending_address = cpu_to_le32(end_kb);
> +        t->extended_starting_address =
> +            t->extended_ending_address = cpu_to_le64(0);
>      } else {
> -        t->starting_address = t->ending_address = UINT32_MAX;
> -        t->extended_starting_address = start;
> -        t->extended_ending_address = end;
> +        t->starting_address = t->ending_address = cpu_to_le32(UINT32_MAX);
> +        t->extended_starting_address = cpu_to_le64(start);
> +        t->extended_ending_address = cpu_to_le64(end);
>      }
> -    t->memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
> +    t->memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
>      t->partition_width = 1; /* One device per row */
>  
>      SMBIOS_BUILD_TABLE_POST;
> @@ -794,14 +796,14 @@ static void smbios_entry_point_setup(void)
>      ep.smbios_bcd_revision = 0x28;
>  
>      /* set during table construction, but BIOS may override: */
> -    ep.structure_table_length = smbios_tables_len;
> -    ep.max_structure_size = smbios_table_max;
> -    ep.number_of_structures = smbios_table_cnt;
> +    ep.structure_table_length = cpu_to_le16(smbios_tables_len);
> +    ep.max_structure_size = cpu_to_le16(smbios_table_max);
> +    ep.number_of_structures = cpu_to_le16(smbios_table_cnt);
>  
>      /* BIOS must recalculate: */
>      ep.checksum = 0;
>      ep.intermediate_checksum = 0;
> -    ep.structure_table_address = 0; /* where BIOS has copied smbios_tables */
> +    ep.structure_table_address = cpu_to_le32(0);
>  }
>  
>  void smbios_get_tables(uint8_t **tables, size_t *tables_len,
> -- 
> 1.9.0
>
diff mbox

Patch

diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 7660718..aeb94bc 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -444,7 +444,7 @@  static bool smbios_skip_table(uint8_t type, bool required_table)
                                                                           \
         t->header.type = tbl_type;                                        \
         t->header.length = sizeof(*t);                                    \
-        t->header.handle = tbl_handle;                                    \
+        t->header.handle = cpu_to_le16(tbl_handle);                       \
     } while (0)
 
 #define SMBIOS_TABLE_SET_STR(tbl_type, field, value)                      \
@@ -491,7 +491,7 @@  static void smbios_build_type_0_table(void)
     SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
     SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
 
-    t->bios_starting_address_segment = 0xE800; /* hardcoded in SeaBIOS */
+    t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
 
     SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
 
@@ -551,7 +551,7 @@  static void smbios_build_type_2_table(void)
     SMBIOS_TABLE_SET_STR(2, asset_tag_number_str, type2.asset);
     t->feature_flags = 0x01; /* Motherboard */
     SMBIOS_TABLE_SET_STR(2, location_str, type2.location);
-    t->chassis_handle = 0x300; /* Type 3 (System enclosure) */
+    t->chassis_handle = cpu_to_le16(0x300); /* Type 3 (System enclosure) */
     t->board_type = 0x0A; /* Motherboard */
     t->contained_element_count = 0;
 
@@ -571,7 +571,7 @@  static void smbios_build_type_3_table(void)
     t->power_supply_state = 0x03; /* Safe */
     t->thermal_state = 0x03; /* Safe */
     t->security_status = 0x02; /* Unknown */
-    t->oem_defined = 0;
+    t->oem_defined = cpu_to_le32(0);
     t->height = 0;
     t->number_of_power_cords = 0;
     t->contained_element_count = 0;
@@ -589,26 +589,27 @@  static void smbios_build_type_4_table(unsigned instance)
     snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
     SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
     t->processor_type = 0x03; /* CPU */
+    t->processor_family = 0x01; /* Other */
     SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer);
-    t->processor_id[0] = smbios_cpuid_version;
-    t->processor_id[1] = smbios_cpuid_features;
+    t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
+    t->processor_id[1] = cpu_to_le32(smbios_cpuid_features);
     SMBIOS_TABLE_SET_STR(4, processor_version_str, type4.version);
     t->voltage = 0;
-    t->external_clock = 0; /* Unknown */
-    t->max_speed = 0; /* Unknown */
-    t->current_speed = 0; /* Unknown */
+    t->external_clock = cpu_to_le16(0); /* Unknown */
+    t->max_speed = cpu_to_le16(0); /* Unknown */
+    t->current_speed = cpu_to_le16(0); /* Unknown */
     t->status = 0x41; /* Socket populated, CPU enabled */
     t->processor_upgrade = 0x01; /* Other */
-    t->l1_cache_handle = 0xFFFF; /* N/A */
-    t->l2_cache_handle = 0xFFFF; /* N/A */
-    t->l3_cache_handle = 0xFFFF; /* N/A */
+    t->l1_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
+    t->l2_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
+    t->l3_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
     SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
     SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
     SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
     t->core_count = t->core_enabled = smp_cores;
     t->thread_count = smp_threads;
-    t->processor_characteristics = 0x02; /* Unknown */
-    t->processor_family = t->processor_family2 = 0x01; /* Other */
+    t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
+    t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
     SMBIOS_BUILD_TABLE_POST;
     smbios_type4_count++;
@@ -631,14 +632,14 @@  static void smbios_build_type_16_table(unsigned dimm_cnt)
     t->error_correction = 0x06; /* Multi-bit ECC (for Microsoft, per SeaBIOS) */
     size_kb = QEMU_ALIGN_UP(ram_size, ONE_KB) / ONE_KB;
     if (size_kb < MAX_T16_STD_SZ) {
-        t->maximum_capacity = size_kb;
-        t->extended_maximum_capacity = 0;
+        t->maximum_capacity = cpu_to_le32(size_kb);
+        t->extended_maximum_capacity = cpu_to_le64(0);
     } else {
-        t->maximum_capacity = MAX_T16_STD_SZ;
-        t->extended_maximum_capacity = ram_size;
+        t->maximum_capacity = cpu_to_le32(MAX_T16_STD_SZ);
+        t->extended_maximum_capacity = cpu_to_le64(ram_size);
     }
-    t->memory_error_information_handle = 0xFFFE; /* Not provided */
-    t->number_of_memory_devices = dimm_cnt;
+    t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
+    t->number_of_memory_devices = cpu_to_le16(dimm_cnt);
 
     SMBIOS_BUILD_TABLE_POST;
 }
@@ -653,18 +654,18 @@  static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
 
     SMBIOS_BUILD_TABLE_PRE(17, 0x1100 + instance, true); /* required */
 
-    t->physical_memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
-    t->memory_error_information_handle = 0xFFFE; /* Not provided */
-    t->total_width = 0xFFFF; /* Unknown */
-    t->data_width = 0xFFFF; /* Unknown */
+    t->physical_memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
+    t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
+    t->total_width = cpu_to_le16(0xFFFF); /* Unknown */
+    t->data_width = cpu_to_le16(0xFFFF); /* Unknown */
     size_mb = QEMU_ALIGN_UP(size, ONE_MB) / ONE_MB;
     if (size_mb < MAX_T17_STD_SZ) {
-        t->size = size_mb;
-        t->extended_size = 0;
+        t->size = cpu_to_le16(size_mb);
+        t->extended_size = cpu_to_le32(0);
     } else {
         assert(size_mb < MAX_T17_EXT_SZ);
-        t->size = MAX_T17_STD_SZ;
-        t->extended_size = size_mb;
+        t->size = cpu_to_le16(MAX_T17_STD_SZ);
+        t->extended_size = cpu_to_le32(size_mb);
     }
     t->form_factor = 0x09; /* DIMM */
     t->device_set = 0; /* Not in a set */
@@ -672,17 +673,17 @@  static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
     SMBIOS_TABLE_SET_STR(17, device_locator_str, loc_str);
     SMBIOS_TABLE_SET_STR(17, bank_locator_str, type17.bank);
     t->memory_type = 0x07; /* RAM */
-    t->type_detail = 0x02; /* Other */
-    t->speed = 0; /* Unknown */
+    t->type_detail = cpu_to_le16(0x02); /* Other */
+    t->speed = cpu_to_le16(0); /* Unknown */
     SMBIOS_TABLE_SET_STR(17, manufacturer_str, type17.manufacturer);
     SMBIOS_TABLE_SET_STR(17, serial_number_str, type17.serial);
     SMBIOS_TABLE_SET_STR(17, asset_tag_number_str, type17.asset);
     SMBIOS_TABLE_SET_STR(17, part_number_str, type17.part);
     t->attributes = 0; /* Unknown */
-    t->configured_clock_speed = 0; /* Unknown */
-    t->minimum_voltage = 0; /* Unknown */
-    t->maximum_voltage = 0; /* Unknown */
-    t->configured_voltage = 0; /* Unknown */
+    t->configured_clock_speed = cpu_to_le32(0); /* Unknown */
+    t->minimum_voltage = cpu_to_le32(0); /* Unknown */
+    t->maximum_voltage = cpu_to_le32(0); /* Unknown */
+    t->configured_voltage = cpu_to_le32(0); /* Unknown */
 
     SMBIOS_BUILD_TABLE_POST;
 }
@@ -699,15 +700,16 @@  static void smbios_build_type_19_table(unsigned instance,
     start_kb = start / ONE_KB;
     end_kb = end / ONE_KB;
     if (start_kb < UINT32_MAX && end_kb < UINT32_MAX) {
-        t->starting_address = start_kb;
-        t->ending_address = end_kb;
-        t->extended_starting_address = t->extended_ending_address = 0;
+        t->starting_address = cpu_to_le32(start_kb);
+        t->ending_address = cpu_to_le32(end_kb);
+        t->extended_starting_address =
+            t->extended_ending_address = cpu_to_le64(0);
     } else {
-        t->starting_address = t->ending_address = UINT32_MAX;
-        t->extended_starting_address = start;
-        t->extended_ending_address = end;
+        t->starting_address = t->ending_address = cpu_to_le32(UINT32_MAX);
+        t->extended_starting_address = cpu_to_le64(start);
+        t->extended_ending_address = cpu_to_le64(end);
     }
-    t->memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
+    t->memory_array_handle = cpu_to_le16(0x1000); /* Type 16 above */
     t->partition_width = 1; /* One device per row */
 
     SMBIOS_BUILD_TABLE_POST;
@@ -794,14 +796,14 @@  static void smbios_entry_point_setup(void)
     ep.smbios_bcd_revision = 0x28;
 
     /* set during table construction, but BIOS may override: */
-    ep.structure_table_length = smbios_tables_len;
-    ep.max_structure_size = smbios_table_max;
-    ep.number_of_structures = smbios_table_cnt;
+    ep.structure_table_length = cpu_to_le16(smbios_tables_len);
+    ep.max_structure_size = cpu_to_le16(smbios_table_max);
+    ep.number_of_structures = cpu_to_le16(smbios_table_cnt);
 
     /* BIOS must recalculate: */
     ep.checksum = 0;
     ep.intermediate_checksum = 0;
-    ep.structure_table_address = 0; /* where BIOS has copied smbios_tables */
+    ep.structure_table_address = cpu_to_le32(0);
 }
 
 void smbios_get_tables(uint8_t **tables, size_t *tables_len,