Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Book3S PR: Emulate PURR, SPURR and DSCR registers

This adds basic emulation of the PURR and SPURR registers. We assume
we are emulating a single-threaded core, so these advance at the same
rate as the timebase. A Linux kernel running on a POWER7 expects to
be able to access these registers and is not prepared to handle a
program interrupt on accessing them.

This also adds a very minimal emulation of the DSCR (data stream
control register). Writes are ignored and reads return zero.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Paul Mackerras and committed by
Alexander Graf
b0a94d4e 1cc8ed0b

+17 -1
+2
arch/powerpc/include/asm/kvm_book3s.h
··· 81 81 u64 sdr1; 82 82 u64 hior; 83 83 u64 msr_mask; 84 + u64 purr_offset; 85 + u64 spurr_offset; 84 86 #ifdef CONFIG_PPC_BOOK3S_32 85 87 u32 vsid_pool[VSID_POOL_SIZE]; 86 88 u32 vsid_next;
+15 -1
arch/powerpc/kvm/book3s_emulate.c
··· 22 22 #include <asm/kvm_book3s.h> 23 23 #include <asm/reg.h> 24 24 #include <asm/switch_to.h> 25 + #include <asm/time.h> 25 26 26 27 #define OP_19_XOP_RFID 18 27 28 #define OP_19_XOP_RFI 50 ··· 396 395 (mfmsr() & MSR_HV)) 397 396 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; 398 397 break; 398 + case SPRN_PURR: 399 + to_book3s(vcpu)->purr_offset = spr_val - get_tb(); 400 + break; 401 + case SPRN_SPURR: 402 + to_book3s(vcpu)->spurr_offset = spr_val - get_tb(); 403 + break; 399 404 case SPRN_GQR0: 400 405 case SPRN_GQR1: 401 406 case SPRN_GQR2: ··· 419 412 case SPRN_CTRLF: 420 413 case SPRN_CTRLT: 421 414 case SPRN_L2CR: 415 + case SPRN_DSCR: 422 416 case SPRN_MMCR0_GEKKO: 423 417 case SPRN_MMCR1_GEKKO: 424 418 case SPRN_PMC1_GEKKO: ··· 491 483 *spr_val = to_book3s(vcpu)->hid[5]; 492 484 break; 493 485 case SPRN_CFAR: 494 - case SPRN_PURR: 486 + case SPRN_DSCR: 495 487 *spr_val = 0; 488 + break; 489 + case SPRN_PURR: 490 + *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; 491 + break; 492 + case SPRN_SPURR: 493 + *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; 496 494 break; 497 495 case SPRN_GQR0: 498 496 case SPRN_GQR1: