|
|
1.1 ! root 1: resolve memory device roll over reporting issues with >32G guests (Bill Rieske) ! 2: ! 3: The field within the Memory Device type 17 is only a word with the MSB being ! 4: used to report MB/KB. Thereby, a guest with 32G and greater would report ! 5: incorrect memory device information rolling over to 0. ! 6: ! 7: This presents more than one memory device and associated memory structures ! 8: if the memory is larger than 16G ! 9: ! 10: Signed-off-by: Bill Rieske <[email protected]> ! 11: Signed-off-by: Avi Kivity <[email protected]> ! 12: Signed-off-by: Anthony Liguori <[email protected]> ! 13: ! 14: Index: bochs/bios/rombios32.c ! 15: =================================================================== ! 16: --- bochs.orig/bios/rombios32.c ! 17: +++ bochs/bios/rombios32.c ! 18: @@ -381,6 +381,17 @@ int vsnprintf(char *buf, int buflen, con ! 19: return buf - buf0; ! 20: } ! 21: ! 22: +int snprintf(char * buf, size_t size, const char *fmt, ...) ! 23: +{ ! 24: + va_list args; ! 25: + int i; ! 26: + ! 27: + va_start(args, fmt); ! 28: + i=vsnprintf(buf,size,fmt,args); ! 29: + va_end(args); ! 30: + return i; ! 31: +} ! 32: + ! 33: void bios_printf(int flags, const char *fmt, ...) ! 34: { ! 35: va_list ap; ! 36: @@ -2039,7 +2050,7 @@ smbios_type_4_init(void *start, unsigned ! 37: ! 38: /* Type 16 -- Physical Memory Array */ ! 39: static void * ! 40: -smbios_type_16_init(void *start, uint32_t memsize) ! 41: +smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs) ! 42: { ! 43: struct smbios_type_16 *p = (struct smbios_type_16*)start; ! 44: ! 45: @@ -2052,7 +2063,7 @@ smbios_type_16_init(void *start, uint32_ ! 46: p->error_correction = 0x01; /* other */ ! 47: p->maximum_capacity = memsize * 1024; ! 48: p->memory_error_information_handle = 0xfffe; /* none provided */ ! 49: - p->number_of_memory_devices = 1; ! 50: + p->number_of_memory_devices = nr_mem_devs; ! 51: ! 52: start += sizeof(struct smbios_type_16); ! 53: *((uint16_t *)start) = 0; ! 54: @@ -2062,20 +2073,19 @@ smbios_type_16_init(void *start, uint32_ ! 55: ! 56: /* Type 17 -- Memory Device */ ! 57: static void * ! 58: -smbios_type_17_init(void *start, uint32_t memory_size_mb) ! 59: +smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance) ! 60: { ! 61: struct smbios_type_17 *p = (struct smbios_type_17 *)start; ! 62: ! 63: p->header.type = 17; ! 64: p->header.length = sizeof(struct smbios_type_17); ! 65: - p->header.handle = 0x1100; ! 66: + p->header.handle = 0x1100 + instance; ! 67: ! 68: p->physical_memory_array_handle = 0x1000; ! 69: p->total_width = 64; ! 70: p->data_width = 64; ! 71: - /* truncate memory_size_mb to 16 bits and clear most significant ! 72: - bit [indicates size in MB] */ ! 73: - p->size = (uint16_t) memory_size_mb & 0x7fff; ! 74: +/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */ ! 75: + p->size = memory_size_mb; ! 76: p->form_factor = 0x09; /* DIMM */ ! 77: p->device_set = 0; ! 78: p->device_locator_str = 1; ! 79: @@ -2084,8 +2094,8 @@ smbios_type_17_init(void *start, uint32_ ! 80: p->type_detail = 0; ! 81: ! 82: start += sizeof(struct smbios_type_17); ! 83: - memcpy((char *)start, "DIMM 1", 7); ! 84: - start += 7; ! 85: + snprintf(start, 8, "DIMM %d", instance); ! 86: + start += strlen(start) + 1; ! 87: *((uint8_t *)start) = 0; ! 88: ! 89: return start+1; ! 90: @@ -2093,16 +2103,16 @@ smbios_type_17_init(void *start, uint32_ ! 91: ! 92: /* Type 19 -- Memory Array Mapped Address */ ! 93: static void * ! 94: -smbios_type_19_init(void *start, uint32_t memory_size_mb) ! 95: +smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance) ! 96: { ! 97: struct smbios_type_19 *p = (struct smbios_type_19 *)start; ! 98: ! 99: p->header.type = 19; ! 100: p->header.length = sizeof(struct smbios_type_19); ! 101: - p->header.handle = 0x1300; ! 102: + p->header.handle = 0x1300 + instance; ! 103: ! 104: - p->starting_address = 0; ! 105: - p->ending_address = (memory_size_mb * 1024) - 1; ! 106: + p->starting_address = instance << 24; ! 107: + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; ! 108: p->memory_array_handle = 0x1000; ! 109: p->partition_width = 1; ! 110: ! 111: @@ -2114,18 +2124,18 @@ smbios_type_19_init(void *start, uint32_ ! 112: ! 113: /* Type 20 -- Memory Device Mapped Address */ ! 114: static void * ! 115: -smbios_type_20_init(void *start, uint32_t memory_size_mb) ! 116: +smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance) ! 117: { ! 118: struct smbios_type_20 *p = (struct smbios_type_20 *)start; ! 119: ! 120: p->header.type = 20; ! 121: p->header.length = sizeof(struct smbios_type_20); ! 122: - p->header.handle = 0x1400; ! 123: + p->header.handle = 0x1400 + instance; ! 124: ! 125: - p->starting_address = 0; ! 126: - p->ending_address = (memory_size_mb * 1024) - 1; ! 127: - p->memory_device_handle = 0x1100; ! 128: - p->memory_array_mapped_address_handle = 0x1300; ! 129: + p->starting_address = instance << 24; ! 130: + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; ! 131: + p->memory_device_handle = 0x1100 + instance; ! 132: + p->memory_array_mapped_address_handle = 0x1300 + instance; ! 133: p->partition_row_position = 1; ! 134: p->interleave_position = 0; ! 135: p->interleaved_data_depth = 0; ! 136: @@ -2176,6 +2186,7 @@ void smbios_init(void) ! 137: char *start, *p, *q; ! 138: int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : ! 139: (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); ! 140: + int i, nr_mem_devs; ! 141: ! 142: #ifdef BX_USE_EBDA_TABLES ! 143: ebda_cur_addr = align(ebda_cur_addr, 16); ! 144: @@ -2187,23 +2198,32 @@ void smbios_init(void) ! 145: ! 146: p = (char *)start + sizeof(struct smbios_entry_point); ! 147: ! 148: -#define add_struct(fn) { \ ! 149: +#define add_struct(fn) do{ \ ! 150: q = (fn); \ ! 151: nr_structs++; \ ! 152: if ((q - p) > max_struct_size) \ ! 153: max_struct_size = q - p; \ ! 154: p = q; \ ! 155: -} ! 156: +}while (0) ! 157: ! 158: add_struct(smbios_type_0_init(p)); ! 159: add_struct(smbios_type_1_init(p)); ! 160: add_struct(smbios_type_3_init(p)); ! 161: for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++) ! 162: add_struct(smbios_type_4_init(p, cpu_num)); ! 163: - add_struct(smbios_type_16_init(p, memsize)); ! 164: - add_struct(smbios_type_17_init(p, memsize)); ! 165: - add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024))); ! 166: - add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024))); ! 167: + ! 168: + /* Each 'memory device' covers up to 16GB of address space. */ ! 169: + nr_mem_devs = (memsize + 0x3fff) >> 14; ! 170: + add_struct(smbios_type_16_init(p, memsize, nr_mem_devs)); ! 171: + for ( i = 0; i < nr_mem_devs; i++ ) ! 172: + { ! 173: + uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) ! 174: + ? (memsize & 0x3fff) : 0x4000); ! 175: + add_struct(smbios_type_17_init(p, dev_memsize, i)); ! 176: + add_struct(smbios_type_19_init(p, dev_memsize, i)); ! 177: + add_struct(smbios_type_20_init(p, dev_memsize, i)); ! 178: + } ! 179: + ! 180: add_struct(smbios_type_32_init(p)); ! 181: add_struct(smbios_type_127_init(p)); ! 182: ! 183: ! 184:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.