KVM: PPC: Book3S HV: Only write DAWR[X] when handling h_set_dawr in real mode
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>
Mon, 17 Jun 2019 07:16:19 +0000 (17:16 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 18 Jun 2019 00:21:19 +0000 (10:21 +1000)
The hcall H_SET_DAWR is used by a guest to set the data address
watchpoint register (DAWR). This hcall is handled in the host in
kvmppc_h_set_dawr() which can be called in either real mode on the
guest exit path from hcall_try_real_mode() in book3s_hv_rmhandlers.S,
or in virtual mode when called from kvmppc_pseries_do_hcall() in
book3s_hv.c.

The function kvmppc_h_set_dawr() updates the dawr and dawrx fields in
the vcpu struct accordingly and then also writes the respective values
into the DAWR and DAWRX registers directly. It is necessary to write
the registers directly here when calling the function in real mode
since the path to re-enter the guest won't do this. However when in
virtual mode the host DAWR and DAWRX values have already been
restored, and so writing the registers would overwrite these.
Additionally there is no reason to write the guest values here as
these will be read from the vcpu struct and written to the registers
appropriately the next time the vcpu is run.

This also avoids the case when handling h_set_dawr for a nested guest
where the guest hypervisor isn't able to write the DAWR and DAWRX
registers directly and must rely on the real hypervisor to do this for
it when it calls H_ENTER_NESTED.

Fixes: c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option")
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kvm/book3s_hv_rmhandlers.S

index 5cb8516b209c458a127f3e8034b035bbc5ebbf36..bc18366cd1ba6116aeb7260de33d67463eb51d57 100644 (file)
@@ -2517,9 +2517,18 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        clrrdi  r4, r4, 3
        std     r4, VCPU_DAWR(r3)
        std     r5, VCPU_DAWRX(r3)
+       /*
+        * If came in through the real mode hcall handler then it is necessary
+        * to write the registers since the return path won't. Otherwise it is
+        * sufficient to store then in the vcpu struct as they will be loaded
+        * next time the vcpu is run.
+        */
+       mfmsr   r6
+       andi.   r6, r6, MSR_DR          /* in real mode? */
+       bne     4f
        mtspr   SPRN_DAWR, r4
        mtspr   SPRN_DAWRX, r5
-       li      r3, 0
+4:     li      r3, 0
        blr
 
 _GLOBAL(kvmppc_h_cede)         /* r3 = vcpu pointer, r11 = msr, r13 = paca */