[qemu+kvm]: trap 寄存器脱敏优化方法

发布时间:2026/5/21 7:05:30

[qemu+kvm]: trap 寄存器脱敏优化方法 敏感寄存器优化SYS_ICC_SGI1R_EL1结论无法脱敏原因在VHE下对icc_sgixr的访问需要trap 而且gicv4.1guest需要写icc_sgixr trap到hypervisorhypervisor通过写GITS_SGIR触发vsgi。优化方法既然无法脱敏只能减少ipi.修改trace 打印guest出写入sgi1r的值发现ipi 0、 ipi 1、 ipi 5 trap次数比较多IPI0 Rescheduling interruptsIPI1Function call interruptsIPI5IRQ work interruptsipi0和ipi5 通过给guest隔离核心可以减少ipiipi1 需要继续抓通过抓smp func的入口获取。发现当guest cpu隔离后 host主要收到的ipi 1 的func是sched_ttwu_pending使能event后可以抓某一个cpu的eventcat per_cpu/cpu1/trace_pipe/tmp/log目前已经抓的event查看cpu都发什么ipi:events/kvm/kvm_handle_sys_reg/查看cpu上收到了那些ipi func events/csd/csd_function_entry/查看cpu都发了哪些ipi func events/ipi/ipi_send_cpu/guest kernel 添加启动参数isolcpusdomain,managed_irq,1-3 nohz_full1-3 rcu_nocbs1-3同时在host进行棒核qemu-affinity pid -k 1 2 3 4 5 6 7 8 这样ipi 1在 1-3核心上少了很多 CPU0 CPU1CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 IPI1:3514578437841784134994366433692538220Function call interrupts通过抓取trace 目前隔离收到大量ipi 1 func:do_noting 和 func: tlb_remove_table_smp_sync;当开启cyclitest时隔离核又发送多个ipi 0resched_curr_lazydo_noting 优化经排查是路径coredump(usermode )-bpf_int_jit_compile-kick_all_cpus_sync-do_nothing原因mirobot_teleoperate.service 不断crashcoredump不断调用bpf抓现场造成频繁ipi广播。解决方法systemctl disable mirobot_teleoperate.servicetlb_remove_table_smp_sync 优化原因guest经常收到此 ipi原因是因为当有umap 等修改页表操作发生时需要flush tlb 在flush tlb前需要全局发送ipi并等待响应。这和kernel 读取页表有关当cpu0 想free 修改页表时 cpu 1 可能正在读取页表由于kernel读取页表采用无锁机制为了快导致free 页表前必须发送全局ipi, 让所有core都处于local irq enable 状态再free页表。 因为读取页表只能在local_irq_disable后读取。无IPICPU1(gup_fast)CPU0(free pagetable)--------------------------------------local_irq_disable()read page tablefree(page_table) read freed memory local_irq_enable()有IPICPU1(gup_fast)CPU0------------------------------------------local_irq_disable()read page table send IPI ───────▶(blocked)read page tablelocal_irq_enable()IPI delivered ✔ IPI handler runs smp_call_function returns ✔free(page_table)✔优化方法 只能尽量减少unmap 修改页表操作。2. guest wfi/wfe 脱敏在wfi和wfe 不脱敏时 guest经常执行wfi陷入到kvm 并且trap时间过长根因是vfio-platform 设备中断会发送kick vcpu vfio_intp_interrupt-vfio_mmap_set_enabled(unmap smmu table)-memory_region_transaction_commit-address_space_update_topology_pass(执行region_del)-MEMORY_LISTENER_CALL_GLOBAL(commit,Forward);-kvm_region_commit-need_inhibittrue-accel_ioctl_inhibit_begin-accel_has_to_wait-cpus_kick_thread(向每个vcpu发送siguser1)此时vcpu在wfi trap 在wfi trapwhile循环里判断current是否有signal pending如果有退出循环进入el0代码简单不帖了。 这样造成wfi trap进入el0代码路径增加trap时间增长。wfi/wfe可脱敏设置hcr.twi HCR.twe 代码gerrit.evad.mioffice.cn如何debug偶尔host隔离core后启动nohz_full后 host无法进入nohz_full如何debug静态tracecat per_cpu/cpu1/trace_pipe , 查看什么业务在core上运行大概率是timer查看timer情况cat /proc/timer_list 查看对应core的active timer 是哪个有没有tick_stop查看cfs: 打开CONFIG_SCHED_DEBUGy查看cat /sys/kernel/debug/sched/debug 观察cfs rq-nr_running, 和available task listguest OS 调度优化guest kernel 启动参数 isolcpusdomain,managed_irq,1-3 nohz_full1-3 rcu_nocbs1-3Host kernel 启动参数isolcpusdomain,managed_irq,1-3 rcu_nocbs1-3 kvm-arm.vgic_v4_enable1 nohz_full1-3guest运行echo1/sys/kernel/debug/tracing/events/irq/irq_handler_entry/enable echo1/sys/kernel/debug/tracing/events/timer/hrtimer_expire_entry/enable echo1/sys/kernel/debug/tracing/events/timer/hrtimer_expire_entry/enable echo1/sys/kernel/debug/tracing/events/irq/irq_handler_entry/enable cyclitest-a1-i1000-p95-t1cat per_cpu/cpu1/trace_pipe情况一cpu idle 唤醒时间长cyclitest 1ms触发一次但是cpuidle唤醒要3ms:原因kernel enable nohz后timer会迁移到非nohz core__hrtimer_start_range_ns-switch_hrtimer_base-get_target_base-切换新的timer base。将timer切换到其他core这样导致timer中断发生在其他core然后通过IPI 对nohz_core唤醒这也解释了为什么log里都是IPI唤醒cpu idle而不是arch_timer。解决方法禁止timer migrationguest中设置echo0/proc/sys/kernel/timer_migration或者修改guest代码kernel/time/timer.c 中 timers_migration_enabled0

相关新闻