]>
Commit | Line | Data |
---|---|---|
4676c0af DM |
1 | Index: kvm-86/cpu-defs.h |
2 | =================================================================== | |
3 | --- kvm-86.orig/cpu-defs.h 2009-09-24 14:19:14.000000000 +0200 | |
4 | +++ kvm-86/cpu-defs.h 2009-09-24 14:47:00.000000000 +0200 | |
5 | @@ -194,6 +194,8 @@ | |
6 | int cpu_index; /* CPU index (informative) */ \ | |
7 | uint32_t host_tid; /* host thread ID */ \ | |
8 | int numa_node; /* NUMA node this cpu is belonging to */ \ | |
9 | + int nr_cores; /* number of cores within this CPU package */ \ | |
10 | + int nr_threads;/* number of threads within this CPU */ \ | |
11 | int running; /* Nonzero if cpu is currently running(usermode). */ \ | |
12 | int thread_id; \ | |
13 | /* user data */ \ | |
14 | Index: kvm-86/target-i386/helper.c | |
15 | =================================================================== | |
16 | --- kvm-86.orig/target-i386/helper.c 2009-09-24 14:19:14.000000000 +0200 | |
17 | +++ kvm-86/target-i386/helper.c 2009-09-24 14:50:18.000000000 +0200 | |
18 | @@ -121,7 +121,7 @@ | |
19 | #ifdef TARGET_X86_64 | |
20 | { | |
21 | .name = "qemu64", | |
22 | - .level = 2, | |
23 | + .level = 4, | |
24 | .vendor1 = CPUID_VENDOR_AMD_1, | |
25 | .vendor2 = CPUID_VENDOR_AMD_2, | |
26 | .vendor3 = CPUID_VENDOR_AMD_3, | |
27 | @@ -192,7 +192,7 @@ | |
28 | #endif | |
29 | { | |
30 | .name = "qemu32", | |
31 | - .level = 2, | |
32 | + .level = 4, | |
33 | .family = 6, | |
34 | .model = 3, | |
35 | .stepping = 3, | |
36 | @@ -1638,6 +1638,12 @@ | |
37 | *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */ | |
38 | *ecx = env->cpuid_ext_features; | |
39 | *edx = env->cpuid_features; | |
40 | + | |
41 | + if (env->nr_cores * env->nr_threads > 1) { | |
42 | + *ebx |= (env->nr_cores * env->nr_threads) << 16; | |
43 | + *edx |= 1 << 28; /* HTT bit */ | |
44 | + } | |
45 | + | |
46 | break; | |
47 | case 2: | |
48 | /* cache info: needed for Pentium Pro compatibility */ | |
49 | @@ -1648,21 +1654,29 @@ | |
50 | break; | |
51 | case 4: | |
52 | /* cache info: needed for Core compatibility */ | |
53 | + if (env->nr_cores > 1) { | |
54 | + *eax = (env->nr_cores - 1) << 26; | |
55 | + } else { | |
56 | + *eax = 0; | |
57 | + } | |
58 | switch (count) { | |
59 | case 0: /* L1 dcache info */ | |
60 | - *eax = 0x0000121; | |
61 | + *eax |= 0x0000121; | |
62 | *ebx = 0x1c0003f; | |
63 | *ecx = 0x000003f; | |
64 | *edx = 0x0000001; | |
65 | break; | |
66 | case 1: /* L1 icache info */ | |
67 | - *eax = 0x0000122; | |
68 | + *eax |= 0x0000122; | |
69 | *ebx = 0x1c0003f; | |
70 | *ecx = 0x000003f; | |
71 | *edx = 0x0000001; | |
72 | break; | |
73 | case 2: /* L2 cache info */ | |
74 | - *eax = 0x0000143; | |
75 | + *eax |= 0x0000143; | |
76 | + if (env->nr_threads > 1) { | |
77 | + *eax |= (env->nr_threads - 1) << 14; | |
78 | + } | |
79 | *ebx = 0x3c0003f; | |
80 | *ecx = 0x0000fff; | |
81 | *edx = 0x0000001; | |
82 | @@ -1715,6 +1729,16 @@ | |
83 | *ecx = env->cpuid_ext3_features; | |
84 | *edx = env->cpuid_ext2_features; | |
85 | ||
86 | + if (env->nr_cores * env->nr_threads > 1) { | |
87 | + uint32_t teax, tebx, tecx, tedx; | |
88 | + cpu_x86_cpuid(env, 0, 0, &teax, &tebx, &tecx, &tedx); | |
89 | + if ( tebx == CPUID_VENDOR_AMD_1 && | |
90 | + tedx == CPUID_VENDOR_AMD_2 && | |
91 | + tecx == CPUID_VENDOR_AMD_3) { | |
92 | + *ecx |= 1 << 1; /* CmpLegacy bit */ | |
93 | + } | |
94 | + } | |
95 | + | |
96 | if (kvm_enabled()) { | |
97 | uint32_t h_eax, h_edx; | |
98 | ||
99 | @@ -1790,6 +1814,9 @@ | |
100 | *ebx = 0; | |
101 | *ecx = 0; | |
102 | *edx = 0; | |
103 | + if (env->nr_cores * env->nr_threads > 1) { | |
104 | + *ecx |= (env->nr_cores * env->nr_threads) - 1; | |
105 | + } | |
106 | break; | |
107 | case 0x8000000A: | |
108 | *eax = 0x00000001; /* SVM Revision */ | |
109 | Index: kvm-86/vl.c | |
110 | =================================================================== | |
111 | --- kvm-86.orig/vl.c 2009-09-24 14:30:14.000000000 +0200 | |
112 | +++ kvm-86/vl.c 2009-09-24 14:47:00.000000000 +0200 | |
113 | @@ -230,6 +230,8 @@ | |
114 | const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE]; | |
115 | int assigned_devices_index; | |
116 | int smp_cpus = 1; | |
117 | +int smp_cores = 1; | |
118 | +int smp_threads = 1; | |
119 | int fairsched_id = 0; | |
120 | const char *vnc_display; | |
121 | int acpi_enabled = 1; | |
122 | @@ -2499,6 +2501,52 @@ | |
123 | return; | |
124 | } | |
125 | ||
126 | +static void smp_parse(const char *optarg) | |
127 | +{ | |
128 | + int smp, sockets = 0, threads = 0, cores = 0; | |
129 | + char *endptr; | |
130 | + char option[128]; | |
131 | + | |
132 | + smp = strtoul(optarg, &endptr, 10); | |
133 | + if (endptr != optarg) { | |
134 | + if (*endptr == ',') { | |
135 | + endptr++; | |
136 | + } | |
137 | + } | |
138 | + if (get_param_value(option, 128, "sockets", endptr) != 0) | |
139 | + sockets = strtoull(option, NULL, 10); | |
140 | + if (get_param_value(option, 128, "cores", endptr) != 0) | |
141 | + cores = strtoull(option, NULL, 10); | |
142 | + if (get_param_value(option, 128, "threads", endptr) != 0) | |
143 | + threads = strtoull(option, NULL, 10); | |
144 | + | |
145 | + /* compute missing values, prefer sockets over cores over threads */ | |
146 | + if (smp == 0 || sockets == 0) { | |
147 | + sockets = sockets > 0 ? sockets : 1; | |
148 | + cores = cores > 0 ? cores : 1; | |
149 | + threads = threads > 0 ? threads : 1; | |
150 | + if (smp == 0) { | |
151 | + smp = cores * threads * sockets; | |
152 | + } else { | |
153 | + sockets = smp / (cores * threads); | |
154 | + } | |
155 | + } else { | |
156 | + if (cores == 0) { | |
157 | + threads = threads > 0 ? threads : 1; | |
158 | + cores = smp / (sockets * threads); | |
159 | + } else { | |
160 | + if (sockets == 0) { | |
161 | + sockets = smp / (cores * threads); | |
162 | + } else { | |
163 | + threads = smp / (cores * sockets); | |
164 | + } | |
165 | + } | |
166 | + } | |
167 | + smp_cpus = smp; | |
168 | + smp_cores = cores > 0 ? cores : 1; | |
169 | + smp_threads = threads > 0 ? threads : 1; | |
170 | +} | |
171 | + | |
172 | /***********************************************************/ | |
173 | /* USB devices */ | |
174 | ||
175 | @@ -3727,6 +3775,8 @@ | |
176 | ||
177 | if (kvm_enabled()) | |
178 | kvm_init_vcpu(env); | |
179 | + env->nr_cores = smp_cores; | |
180 | + env->nr_threads = smp_threads; | |
181 | return; | |
182 | } | |
183 | ||
184 | @@ -4060,6 +4110,8 @@ | |
185 | kvm_start_vcpu(env); | |
186 | else | |
187 | tcg_init_vcpu(env); | |
188 | + env->nr_cores = smp_cores; | |
189 | + env->nr_threads = smp_threads; | |
190 | } | |
191 | ||
192 | void qemu_notify_event(void) | |
193 | @@ -5560,7 +5612,7 @@ | |
194 | usb_devices_index++; | |
195 | break; | |
196 | case QEMU_OPTION_smp: | |
197 | - smp_cpus = atoi(optarg); | |
198 | + smp_parse(optarg); | |
199 | if (smp_cpus < 1) { | |
200 | fprintf(stderr, "Invalid number of CPUs\n"); | |
201 | exit(1); |