aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/44x_emulate.c
diff options
context:
space:
mode:
authorHollis Blanchard <hollisb@us.ibm.com>2008-11-05 10:36:23 -0500
committerAvi Kivity <avi@redhat.com>2008-12-31 09:52:23 -0500
commitd4cf3892e50b8e35341086a4fe2bb8a3989b55d4 (patch)
treeadb3275c9d5a2a89605b705434e57e1d0fc48ae6 /arch/powerpc/kvm/44x_emulate.c
parent9ab80843c01ac25139e635d018467e528729a317 (diff)
KVM: ppc: optimize irq delivery path
In kvmppc_deliver_interrupt is just one case left in the switch and it is a rare one (less than 8%) when looking at the exit numbers. Therefore we can at least drop the switch/case and if an if. I inserted an unlikely too, but that's open for discussion. In kvmppc_can_deliver_interrupt all frequent cases are in the default case. I know compilers are smart but we can make it easier for them. By writing down all options and removing the default case combined with the fact that ithe values are constants 0..15 should allow the compiler to write an easy jump table. Modifying kvmppc_can_deliver_interrupt pointed me to the fact that gcc seems to be unable to reduce priority_exception[x] to a build time constant. Therefore I changed the usage of the translation arrays in the interrupt delivery path completely. It is now using priority without translation to irq on the full irq delivery path. To be able to do that ivpr regs are stored by their priority now. Additionally the decision made in kvmppc_can_deliver_interrupt is already sufficient to get the value of interrupt_msr_mask[x]. Therefore we can replace the 16x4byte array used here with a single 4byte variable (might still be one miss, but the chance to find this in cache should be better than the right entry of the whole array). Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/44x_emulate.c')
-rw-r--r--arch/powerpc/kvm/44x_emulate.c100
1 files changed, 67 insertions, 33 deletions
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c
index a634c0c4fa7e..9bc50cebf9ec 100644
--- a/arch/powerpc/kvm/44x_emulate.c
+++ b/arch/powerpc/kvm/44x_emulate.c
@@ -228,39 +228,56 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
228 vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break; 228 vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
229 229
230 case SPRN_IVPR: 230 case SPRN_IVPR:
231 vcpu->arch.ivpr = vcpu->arch.gpr[rs]; break; 231 vcpu->arch.ivpr = vcpu->arch.gpr[rs];
232 break;
232 case SPRN_IVOR0: 233 case SPRN_IVOR0:
233 vcpu->arch.ivor[0] = vcpu->arch.gpr[rs]; break; 234 vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
235 break;
234 case SPRN_IVOR1: 236 case SPRN_IVOR1:
235 vcpu->arch.ivor[1] = vcpu->arch.gpr[rs]; break; 237 vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
238 break;
236 case SPRN_IVOR2: 239 case SPRN_IVOR2:
237 vcpu->arch.ivor[2] = vcpu->arch.gpr[rs]; break; 240 vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
241 break;
238 case SPRN_IVOR3: 242 case SPRN_IVOR3:
239 vcpu->arch.ivor[3] = vcpu->arch.gpr[rs]; break; 243 vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
244 break;
240 case SPRN_IVOR4: 245 case SPRN_IVOR4:
241 vcpu->arch.ivor[4] = vcpu->arch.gpr[rs]; break; 246 vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
247 break;
242 case SPRN_IVOR5: 248 case SPRN_IVOR5:
243 vcpu->arch.ivor[5] = vcpu->arch.gpr[rs]; break; 249 vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
250 break;
244 case SPRN_IVOR6: 251 case SPRN_IVOR6:
245 vcpu->arch.ivor[6] = vcpu->arch.gpr[rs]; break; 252 vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
253 break;
246 case SPRN_IVOR7: 254 case SPRN_IVOR7:
247 vcpu->arch.ivor[7] = vcpu->arch.gpr[rs]; break; 255 vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
256 break;
248 case SPRN_IVOR8: 257 case SPRN_IVOR8:
249 vcpu->arch.ivor[8] = vcpu->arch.gpr[rs]; break; 258 vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
259 break;
250 case SPRN_IVOR9: 260 case SPRN_IVOR9:
251 vcpu->arch.ivor[9] = vcpu->arch.gpr[rs]; break; 261 vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
262 break;
252 case SPRN_IVOR10: 263 case SPRN_IVOR10:
253 vcpu->arch.ivor[10] = vcpu->arch.gpr[rs]; break; 264 vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
265 break;
254 case SPRN_IVOR11: 266 case SPRN_IVOR11:
255 vcpu->arch.ivor[11] = vcpu->arch.gpr[rs]; break; 267 vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
268 break;
256 case SPRN_IVOR12: 269 case SPRN_IVOR12:
257 vcpu->arch.ivor[12] = vcpu->arch.gpr[rs]; break; 270 vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
271 break;
258 case SPRN_IVOR13: 272 case SPRN_IVOR13:
259 vcpu->arch.ivor[13] = vcpu->arch.gpr[rs]; break; 273 vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
274 break;
260 case SPRN_IVOR14: 275 case SPRN_IVOR14:
261 vcpu->arch.ivor[14] = vcpu->arch.gpr[rs]; break; 276 vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
277 break;
262 case SPRN_IVOR15: 278 case SPRN_IVOR15:
263 vcpu->arch.ivor[15] = vcpu->arch.gpr[rs]; break; 279 vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
280 break;
264 281
265 default: 282 default:
266 return EMULATE_FAIL; 283 return EMULATE_FAIL;
@@ -295,37 +312,54 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
295 vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break; 312 vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
296 313
297 case SPRN_IVOR0: 314 case SPRN_IVOR0:
298 vcpu->arch.gpr[rt] = vcpu->arch.ivor[0]; break; 315 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
316 break;
299 case SPRN_IVOR1: 317 case SPRN_IVOR1:
300 vcpu->arch.gpr[rt] = vcpu->arch.ivor[1]; break; 318 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
319 break;
301 case SPRN_IVOR2: 320 case SPRN_IVOR2:
302 vcpu->arch.gpr[rt] = vcpu->arch.ivor[2]; break; 321 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
322 break;
303 case SPRN_IVOR3: 323 case SPRN_IVOR3:
304 vcpu->arch.gpr[rt] = vcpu->arch.ivor[3]; break; 324 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
325 break;
305 case SPRN_IVOR4: 326 case SPRN_IVOR4:
306 vcpu->arch.gpr[rt] = vcpu->arch.ivor[4]; break; 327 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
328 break;
307 case SPRN_IVOR5: 329 case SPRN_IVOR5:
308 vcpu->arch.gpr[rt] = vcpu->arch.ivor[5]; break; 330 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
331 break;
309 case SPRN_IVOR6: 332 case SPRN_IVOR6:
310 vcpu->arch.gpr[rt] = vcpu->arch.ivor[6]; break; 333 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
334 break;
311 case SPRN_IVOR7: 335 case SPRN_IVOR7:
312 vcpu->arch.gpr[rt] = vcpu->arch.ivor[7]; break; 336 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
337 break;
313 case SPRN_IVOR8: 338 case SPRN_IVOR8:
314 vcpu->arch.gpr[rt] = vcpu->arch.ivor[8]; break; 339 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
340 break;
315 case SPRN_IVOR9: 341 case SPRN_IVOR9:
316 vcpu->arch.gpr[rt] = vcpu->arch.ivor[9]; break; 342 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
343 break;
317 case SPRN_IVOR10: 344 case SPRN_IVOR10:
318 vcpu->arch.gpr[rt] = vcpu->arch.ivor[10]; break; 345 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
346 break;
319 case SPRN_IVOR11: 347 case SPRN_IVOR11:
320 vcpu->arch.gpr[rt] = vcpu->arch.ivor[11]; break; 348 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
349 break;
321 case SPRN_IVOR12: 350 case SPRN_IVOR12:
322 vcpu->arch.gpr[rt] = vcpu->arch.ivor[12]; break; 351 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
352 break;
323 case SPRN_IVOR13: 353 case SPRN_IVOR13:
324 vcpu->arch.gpr[rt] = vcpu->arch.ivor[13]; break; 354 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
355 break;
325 case SPRN_IVOR14: 356 case SPRN_IVOR14:
326 vcpu->arch.gpr[rt] = vcpu->arch.ivor[14]; break; 357 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
358 break;
327 case SPRN_IVOR15: 359 case SPRN_IVOR15:
328 vcpu->arch.gpr[rt] = vcpu->arch.ivor[15]; break; 360 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
361 break;
362
329 default: 363 default:
330 return EMULATE_FAIL; 364 return EMULATE_FAIL;
331 } 365 }