qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/ppc: Implement the VTB for HV access

The virtual timebase register (VTB) is a 64-bit register which
increments at the same rate as the timebase register, present on POWER8
and later processors.

The register is able to be read/written by the hypervisor and read by
the supervisor. All other accesses are illegal.

Currently the VTB is just an alias for the timebase (TB) register.

Implement the VTB so that is can be read/written independent of the TB.
Make use of the existing method for accessing timebase facilities where
by the compensation is stored and used to compute the value on reads/is
updated on writes.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
[ clg: rebased on current ppc tree ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191128134700.16091-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

authored by

Suraj Jitindar Singh and committed by
David Gibson
5d62725b 2661f6ab

+51 -4
+16
hw/ppc/ppc.c
··· 682 682 &tb_env->atb_offset, ((uint64_t)value << 32) | tb); 683 683 } 684 684 685 + uint64_t cpu_ppc_load_vtb(CPUPPCState *env) 686 + { 687 + ppc_tb_t *tb_env = env->tb_env; 688 + 689 + return cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 690 + tb_env->vtb_offset); 691 + } 692 + 693 + void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value) 694 + { 695 + ppc_tb_t *tb_env = env->tb_env; 696 + 697 + cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 698 + &tb_env->vtb_offset, value); 699 + } 700 + 685 701 static void cpu_ppc_tb_stop (CPUPPCState *env) 686 702 { 687 703 ppc_tb_t *tb_env = env->tb_env;
+1
include/hw/ppc/ppc.h
··· 24 24 /* Time base management */ 25 25 int64_t tb_offset; /* Compensation */ 26 26 int64_t atb_offset; /* Compensation */ 27 + int64_t vtb_offset; 27 28 uint32_t tb_freq; /* TB frequency */ 28 29 /* Decrementer management */ 29 30 uint64_t decr_next; /* Tick for next decr interrupt */
+5
linux-user/ppc/cpu_loop.c
··· 47 47 return cpu_ppc_get_tb(env) >> 32; 48 48 } 49 49 50 + uint64_t cpu_ppc_load_vtb(CPUPPCState *env) 51 + { 52 + return cpu_ppc_get_tb(env); 53 + } 54 + 50 55 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env) 51 56 __attribute__ (( alias ("cpu_ppc_load_tbu") )); 52 57
+2
target/ppc/cpu.h
··· 1303 1303 uint32_t cpu_ppc_load_atbu(CPUPPCState *env); 1304 1304 void cpu_ppc_store_atbl(CPUPPCState *env, uint32_t value); 1305 1305 void cpu_ppc_store_atbu(CPUPPCState *env, uint32_t value); 1306 + uint64_t cpu_ppc_load_vtb(CPUPPCState *env); 1307 + void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value); 1306 1308 bool ppc_decr_clear_on_delivery(CPUPPCState *env); 1307 1309 target_ulong cpu_ppc_load_decr(CPUPPCState *env); 1308 1310 void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
+2
target/ppc/helper.h
··· 649 649 DEF_HELPER_FLAGS_1(load_tbu, TCG_CALL_NO_RWG, tl, env) 650 650 DEF_HELPER_FLAGS_1(load_atbl, TCG_CALL_NO_RWG, tl, env) 651 651 DEF_HELPER_FLAGS_1(load_atbu, TCG_CALL_NO_RWG, tl, env) 652 + DEF_HELPER_FLAGS_1(load_vtb, TCG_CALL_NO_RWG, tl, env) 652 653 DEF_HELPER_FLAGS_1(load_601_rtcl, TCG_CALL_NO_RWG, tl, env) 653 654 DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env) 654 655 #if !defined(CONFIG_USER_ONLY) ··· 669 670 DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl) 670 671 DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env) 671 672 DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl) 673 + DEF_HELPER_FLAGS_2(store_vtb, TCG_CALL_NO_RWG, void, env, tl) 672 674 DEF_HELPER_2(store_hid0_601, void, env, tl) 673 675 DEF_HELPER_3(store_403_pbr, void, env, i32, tl) 674 676 DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
+10
target/ppc/timebase_helper.c
··· 45 45 return cpu_ppc_load_atbu(env); 46 46 } 47 47 48 + target_ulong helper_load_vtb(CPUPPCState *env) 49 + { 50 + return cpu_ppc_load_vtb(env); 51 + } 52 + 48 53 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 49 54 target_ulong helper_load_purr(CPUPPCState *env) 50 55 { ··· 111 116 void helper_store_hdecr(CPUPPCState *env, target_ulong val) 112 117 { 113 118 cpu_ppc_store_hdecr(env, val); 119 + } 120 + 121 + void helper_store_vtb(CPUPPCState *env, target_ulong val) 122 + { 123 + cpu_ppc_store_vtb(env, val); 114 124 } 115 125 116 126 target_ulong helper_load_40x_pit(CPUPPCState *env)
+15 -4
target/ppc/translate_init.inc.c
··· 312 312 } 313 313 } 314 314 315 + static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn) 316 + { 317 + gen_helper_load_vtb(cpu_gpr[gprn], cpu_env); 318 + } 319 + 320 + static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn) 321 + { 322 + gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]); 323 + } 324 + 315 325 #endif 316 326 #endif 317 327 ··· 8174 8184 /* Virtual Time Base */ 8175 8185 static void gen_spr_vtb(CPUPPCState *env) 8176 8186 { 8177 - spr_register_kvm(env, SPR_VTB, "VTB", 8178 - SPR_NOACCESS, SPR_NOACCESS, 8179 - &spr_read_tbl, SPR_NOACCESS, 8180 - KVM_REG_PPC_VTB, 0x00000000); 8187 + spr_register_kvm_hv(env, SPR_VTB, "VTB", 8188 + SPR_NOACCESS, SPR_NOACCESS, 8189 + &spr_read_vtb, SPR_NOACCESS, 8190 + &spr_read_vtb, &spr_write_vtb, 8191 + KVM_REG_PPC_VTB, 0x00000000); 8181 8192 } 8182 8193 8183 8194 static void gen_spr_power8_fscr(CPUPPCState *env)