@@ -11,4 +11,5 @@
#define UV_WRITE_PATE 0xf104
#define UV_RESTRICTED_SPR_WRITE 0xf108
#define UV_RESTRICTED_SPR_READ 0xf10C
+#define UV_RETURN 0xf11C
#endif /* #ifndef UAPI_UC_H */
@@ -35,6 +35,7 @@
#include <asm/thread_info.h>
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
+#include <asm/ucall-api.h>
/* Sign-extend HDEC if not on POWER9 */
#define EXTEND_HDEC(reg) \
@@ -1092,15 +1093,12 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ld r5, VCPU_LR(r4)
- ld r6, VCPU_CR(r4)
mtlr r5
- mtcr r6
ld r1, VCPU_GPR(R1)(r4)
ld r2, VCPU_GPR(R2)(r4)
ld r3, VCPU_GPR(R3)(r4)
ld r5, VCPU_GPR(R5)(r4)
- ld r6, VCPU_GPR(R6)(r4)
ld r7, VCPU_GPR(R7)(r4)
ld r8, VCPU_GPR(R8)(r4)
ld r9, VCPU_GPR(R9)(r4)
@@ -1119,10 +1117,33 @@ BEGIN_FTR_SECTION
mtspr SPRN_HDSISR, r0
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+ mfspr r6, SPRN_HSRR1
+ andis. r6, r6, MSR_S@high
+ cmplwi r6, 0
+ bne ret_to_ultra;
+
+ lwz r6, VCPU_CR(r4)
+ mtcr r6
+
+ ld r6, VCPU_GPR(R6)(r4)
ld r0, VCPU_GPR(R0)(r4)
ld r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b .
+/*
+ * The hcall we just completed was from Ultravisor. Use UV_RETURN
+ * ultra call to return to the Ultravisor. Results from the hcall
+ * are already in the appropriate registers (r3:12), except for
+ * R6 which we used as a temporary register above. Restore that,
+ * and set R0 to the ucall number (UV_RETURN).
+ */
+ret_to_ultra:
+ lwz r6, VCPU_CR(r4)
+ mtcr r6
+ LOAD_REG_IMMEDIATE(r0, UV_RETURN)
+ ld r6, VCPU_GPR(R6)(r4)
+ ld r4, VCPU_GPR(R4)(r4)
+ sc 2
/*
* Enter the guest on a P9 or later system where we have exactly