|
|
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.