@samitouri / QOSamiQemu / commits / e2beafde9e

target/riscv/kvm: skip FP/Vector sync on KVM_PUT_RUNTIME_STATE

During KVM exit processing (KVM_PUT_RUNTIME_STATE), QEMU never modifies FP or Vector registers — only core GPRs/PC and CSRs are potentially changed. Re-syncing 32 FP and 32 Vector registers on every KVM exit wastes 36-68 individual KVM_SET_ONE_REG ioctls per vCPU exit. Follow the s390x pattern: early return on RUNTIME after syncing core registers and CSRs. KVM_PUT_FULL_STATE and KVM_PUT_RESET_STATE continue to sync everything for correctness during migration and initialization. Signed-off-by: Meng Zhuo <mengzhuo@iscas.ac.cn> Acked-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com> Message-ID: <20260518102118.2768383-1-mengzhuo@iscas.ac.cn> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Meng Zhuo committed May 18, 2026 at 18:21 UTC e2beafde9e782b051355975f444c986b1b788925
1 file changed +14 -5
target/riscv/kvm/kvm-cpu.c
+14 -5
@@ -1395,6 +1395,17 @@ int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp)
1395 return ret;
1396 }
1397
1398 + /*
1399 + * For RUNTIME_STATE, KVM already has the correct FP and Vector state
1400 + * from the preceding KVM_RUN exit. QEMU never modifies these registers
1401 + * during exit handling, so re-syncing is unnecessary. This saves ~68
1402 + * KVM_SET_ONE_REG ioctls per vCPU exit. See also s390x which uses
1403 + * the same pattern.
1404 + */
1405 + if (KVM_PUT_RUNTIME_STATE == level) {
1406 + return ret;
1407 + }
1408 +
1409 ret = kvm_riscv_put_regs_fp(cs);
1410 if (ret) {
1411 return ret;
@@ -1407,11 +1418,9 @@ int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp)
1418
1419 if (KVM_PUT_RESET_STATE == level) {
1420 RISCVCPU *cpu = RISCV_CPU(cs);
1410 - if (cs->cpu_index == 0) {
1411 - ret = kvm_riscv_sync_mpstate_to_kvm(cpu, KVM_MP_STATE_RUNNABLE);
1412 - } else {
1413 - ret = kvm_riscv_sync_mpstate_to_kvm(cpu, KVM_MP_STATE_STOPPED);
1414 - }
1421 + int state = cs->cpu_index == 0 ? KVM_MP_STATE_RUNNABLE
1422 + : KVM_MP_STATE_STOPPED;
1423 + ret = kvm_riscv_sync_mpstate_to_kvm(cpu, state);
1424 if (ret) {
1425 return ret;
1426 }