mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
KVM: PPC: Reduce reliance on analyse_instr() in mmio emulation
Commit7092360399
("KVM: PPC: Reimplement non-SIMD LOAD/STORE instruction mmio emulation with analyse_instr() input") and commit2b33cb585f
("KVM: PPC: Reimplement LOAD_FP/STORE_FP instruction mmio emulation with analyse_instr() input") made kvmppc_emulate_loadstore() use the results from analyse_instr() for instruction emulation. In particular the effective address from analyse_instr() is used for UPDATE type instructions and fact that op.val is all ready endian corrected is used in the STORE case. However, these changes now have some negative implications for the nestedv2 case. For analyse_instr() to determine the correct effective address, the GPRs must be loaded from the L0. This is not needed as vcpu->arch.vaddr_accessed is already set. Change back to using vcpu->arch.vaddr_accessed. In the STORE case, use kvmppc_get_gpr() value instead of the op.val. kvmppc_get_gpr() will reload from the L0 if needed in the nestedv2 case. This means if a byte reversal is needed must now be passed to kvmppc_handle_store() like in the kvmppc_handle_load() case. This means the call to kvmhv_nestedv2_reload_ptregs() can be avoided as there is no concern about op.val being stale. Drop the call to kvmhv_nestedv2_mark_dirty_ptregs() as without the call to kvmhv_nestedv2_reload_ptregs(), stale state could be marked as valid. This is fine as the required marking things dirty is already handled for the UPDATE case by the call to kvmppc_set_gpr(). For LOADs, it is handled in kvmppc_complete_mmio_load(). This is called either directly in __kvmppc_handle_load() if the load can be handled in KVM, or on the next kvm_arch_vcpu_ioctl_run() if an exit was required. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20231201132618.555031-12-vaibhav@linux.ibm.com
This commit is contained in:
parent
db1dcfae1d
commit
797a5af8fc
@ -93,7 +93,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
|
||||
emulated = EMULATE_FAIL;
|
||||
vcpu->arch.regs.msr = kvmppc_get_msr(vcpu);
|
||||
kvmhv_nestedv2_reload_ptregs(vcpu, &vcpu->arch.regs);
|
||||
if (analyse_instr(&op, &vcpu->arch.regs, inst) == 0) {
|
||||
int type = op.type & INSTR_TYPE_MASK;
|
||||
int size = GETSIZE(op.type);
|
||||
@ -112,7 +111,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
op.reg, size, !instr_byte_swap);
|
||||
|
||||
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -132,7 +131,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
KVM_MMIO_REG_FPR|op.reg, size, 1);
|
||||
|
||||
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
|
||||
|
||||
break;
|
||||
#endif
|
||||
@ -224,16 +223,17 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case STORE:
|
||||
/* if need byte reverse, op.val has been reversed by
|
||||
* analyse_instr().
|
||||
*/
|
||||
emulated = kvmppc_handle_store(vcpu, op.val, size, 1);
|
||||
case STORE: {
|
||||
int instr_byte_swap = op.type & BYTEREV;
|
||||
|
||||
emulated = kvmppc_handle_store(vcpu, kvmppc_get_gpr(vcpu, op.reg),
|
||||
size, !instr_byte_swap);
|
||||
|
||||
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
|
||||
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_PPC_FPU
|
||||
case STORE_FP:
|
||||
if (kvmppc_check_fp_disabled(vcpu))
|
||||
@ -254,7 +254,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
kvmppc_get_fpr(vcpu, op.reg), size, 1);
|
||||
|
||||
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
|
||||
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
|
||||
|
||||
break;
|
||||
#endif
|
||||
@ -358,7 +358,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
trace_kvm_ppc_instr(ppc_inst_val(inst), kvmppc_get_pc(vcpu), emulated);
|
||||
kvmhv_nestedv2_mark_dirty_ptregs(vcpu, &vcpu->arch.regs);
|
||||
|
||||
/* Advance past emulated instruction. */
|
||||
if (emulated != EMULATE_FAIL)
|
||||
|
Loading…
Reference in New Issue
Block a user