|
@@ -69,12 +69,14 @@ enum label_id {
|
|
label_msa_1,
|
|
label_msa_1,
|
|
label_return_to_host,
|
|
label_return_to_host,
|
|
label_kernel_asid,
|
|
label_kernel_asid,
|
|
|
|
+ label_exit_common,
|
|
};
|
|
};
|
|
|
|
|
|
UASM_L_LA(_fpu_1)
|
|
UASM_L_LA(_fpu_1)
|
|
UASM_L_LA(_msa_1)
|
|
UASM_L_LA(_msa_1)
|
|
UASM_L_LA(_return_to_host)
|
|
UASM_L_LA(_return_to_host)
|
|
UASM_L_LA(_kernel_asid)
|
|
UASM_L_LA(_kernel_asid)
|
|
|
|
+UASM_L_LA(_exit_common)
|
|
|
|
|
|
static void *kvm_mips_build_enter_guest(void *addr);
|
|
static void *kvm_mips_build_enter_guest(void *addr);
|
|
static void *kvm_mips_build_ret_from_exit(void *addr);
|
|
static void *kvm_mips_build_ret_from_exit(void *addr);
|
|
@@ -327,15 +329,23 @@ static void *kvm_mips_build_enter_guest(void *addr)
|
|
/**
|
|
/**
|
|
* kvm_mips_build_exception() - Assemble first level guest exception handler.
|
|
* kvm_mips_build_exception() - Assemble first level guest exception handler.
|
|
* @addr: Address to start writing code.
|
|
* @addr: Address to start writing code.
|
|
|
|
+ * @handler: Address of common handler (within range of @addr).
|
|
*
|
|
*
|
|
* Assemble exception vector code for guest execution. The generated vector will
|
|
* Assemble exception vector code for guest execution. The generated vector will
|
|
- * jump to the common exception handler generated by kvm_mips_build_exit().
|
|
|
|
|
|
+ * branch to the common exception handler generated by kvm_mips_build_exit().
|
|
*
|
|
*
|
|
* Returns: Next address after end of written function.
|
|
* Returns: Next address after end of written function.
|
|
*/
|
|
*/
|
|
-void *kvm_mips_build_exception(void *addr)
|
|
|
|
|
|
+void *kvm_mips_build_exception(void *addr, void *handler)
|
|
{
|
|
{
|
|
u32 *p = addr;
|
|
u32 *p = addr;
|
|
|
|
+ struct uasm_label labels[2];
|
|
|
|
+ struct uasm_reloc relocs[2];
|
|
|
|
+ struct uasm_label *l = labels;
|
|
|
|
+ struct uasm_reloc *r = relocs;
|
|
|
|
+
|
|
|
|
+ memset(labels, 0, sizeof(labels));
|
|
|
|
+ memset(relocs, 0, sizeof(relocs));
|
|
|
|
|
|
/* Save guest k0 */
|
|
/* Save guest k0 */
|
|
uasm_i_mtc0(&p, K0, scratch_tmp[0], scratch_tmp[1]);
|
|
uasm_i_mtc0(&p, K0, scratch_tmp[0], scratch_tmp[1]);
|
|
@@ -349,12 +359,13 @@ void *kvm_mips_build_exception(void *addr)
|
|
/* Save k1 @ offset 0x3000 */
|
|
/* Save k1 @ offset 0x3000 */
|
|
UASM_i_SW(&p, K1, 0x3000, K0);
|
|
UASM_i_SW(&p, K1, 0x3000, K0);
|
|
|
|
|
|
- /* Exception handler is installed @ offset 0x2000 */
|
|
|
|
- uasm_i_addiu(&p, K0, K0, 0x2000);
|
|
|
|
- /* Jump to the function */
|
|
|
|
- uasm_i_jr(&p, K0);
|
|
|
|
|
|
+ /* Branch to the common handler */
|
|
|
|
+ uasm_il_b(&p, &r, label_exit_common);
|
|
uasm_i_nop(&p);
|
|
uasm_i_nop(&p);
|
|
|
|
|
|
|
|
+ uasm_l_exit_common(&l, handler);
|
|
|
|
+ uasm_resolve_relocs(relocs, labels);
|
|
|
|
+
|
|
return p;
|
|
return p;
|
|
}
|
|
}
|
|
|
|
|