Re: [PATCH] KVM: SVM: make svm_flush_tlb_gva do a full asid flush if NPT enabled

From: Alexander Lougovski

Date: Thu Jul 30 2026 - 07:23:11 EST


On Tue, Jul 28, 2026 at 03:34:36PM -0600, Tycho Andersen wrote:
> my LLM complained about the '% 2800000', looks like it's selecting
> from 1..2.8M in a 1.6M table, so the updates above 1.6M don't affect
> any rows.

Hi Tycho,
ah, true. Your LLM is correct. I've been experimenting with the different sizes of DB to ensure more memory churn (avoid sql reading from the cache) but then settled back to 1.6M.


Another thing to mention, it looks like 1582 workload version I've shared doesn't work correctly. So I'm attaching an improved version which mitigates problems - the version I shared before, was still generating a noticeable amount of TLB flushes but still wasn't exactly working as it's supposed to. So here is the improved version:

---------8<-------------


$ErrorActionPreference = 'Stop'
$logFile = "C:\drivers\workload-1582-errors.log"

$block = {
param($logFile)
$files = @(
"$env:SystemRoot\System32\ntdll.dll",
"$env:SystemRoot\System32\kernel32.dll",
"$env:SystemRoot\System32\user32.dll",
"$env:SystemRoot\System32\advapi32.dll",
"$env:SystemRoot\System32\ole32.dll",
"$env:SystemRoot\System32\shell32.dll",
"$env:SystemRoot\System32\comctl32.dll",
"$env:SystemRoot\System32\msvcrt.dll"
)
$i = 0
while ($true) {
$f = $files[(Get-Random -Maximum $files.Count)]
try {
$fs = [System.IO.FileStream]::new($f,
[System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read,
[System.IO.FileShare]::Read)
$mmf = [System.IO.MemoryMappedFiles.MemoryMappedFile]::CreateFromFile(
$fs, [NullString]::Value, 0,
[System.IO.MemoryMappedFiles.MemoryMappedFileAccess]::Read,
[System.IO.HandleInheritability]::None, $false)
$view = $mmf.CreateViewAccessor(0, 0,
[System.IO.MemoryMappedFiles.MemoryMappedFileAccess]::Read)
for ($p = 0; $p -lt [Math]::Min($view.Capacity, 65536); $p += 4096) {
$null = $view.ReadByte($p)
}
$view.Dispose()
$mmf.Dispose()
} catch {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') iter=$i file=$f error=$($_.Exception.Message)" | Out-File -Append $logFile
}
$i++
if ($i % 50 -eq 0) {
try {
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
} catch {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') iter=$i GC error=$($_.Exception.Message)" | Out-File -Append $logFile
}
}
}
}

"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Workload1582 starting (PID=$PID)" | Out-File -Append $logFile

try {
1..2 | ForEach-Object {
Start-Job -ScriptBlock $block -ArgumentList $logFile
}

while ($true) {
$jobs = Get-Job
$failed = $jobs | Where-Object { $_.State -eq 'Failed' }
if ($failed) {
foreach ($j in $failed) {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Job $($j.Id) FAILED: $($j.ChildJobs[0].JobStateInfo.Reason)" | Out-File -Append $logFile
Remove-Job $j -Force
Start-Job -ScriptBlock $block -ArgumentList $logFile
}
}
$running = @(Get-Job | Where-Object { $_.State -eq 'Running' })
if ($running.Count -eq 0) {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') ALL JOBS DEAD, restarting" | Out-File -Append $logFile
1..2 | ForEach-Object {
Start-Job -ScriptBlock $block -ArgumentList $logFile
}
}
Start-Sleep -Seconds 60
}
} catch {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') PARENT CAUGHT EXCEPTION: $($_.Exception.GetType().FullName): $($_.Exception.Message)" | Out-File -Append $logFile
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') STACK: $($_.ScriptStackTrace)" | Out-File -Append $logFile
} finally {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') PARENT EXITING (PID=$PID) LastExitCode=$LASTEXITCODE" | Out-File -Append $logFile
}


---------8<-------------


Also here is my qemu cmd:

/usr/libexec/qemu-kvm
-name vm-1,debug-threads=on
-machine pc-q35-rhel9.6.0,usb=off,dump-guest-core=off,hpet=off,acpi=on
-accel kvm
-cpu host,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-reset=on,hv-frequencies=on,hv-tlbflush=on,hv-ipi=on
-m 16384
-object memory-backend-ram,id=ram-node0,size=16G,host-nodes=0,policy=bind
-numa node,nodeid=0,cpus=0-3,memdev=ram-node0
-smp 4,sockets=1,dies=1,cores=4,threads=1
-rtc base=localtime,driftfix=slew
-global kvm-pit.lost_tick_policy=delay
-device virtio-blk-pci,drive=drive0,write-cache=on
-drive file=/mnt/nfs-fleet/vm-1.raw,if=none,id=drive0,format=raw,aio=native,cache.direct=on,discard=unmap
-device virtio-net-pci,netdev=net0,mac=XX:XX:XX:XX:XX:XX,mq=on,vectors=18,host_mtu=9000
-netdev tap,id=net0,ifname=tap1,script=no,downscript=no
-device virtio-serial-pci
-device virtio-balloon-pci
-device virtio-rng-pci,rng=objrng0
-object rng-random,id=objrng0,filename=/dev/urandom
-device vmcoreinfo
-vga virtio
-serial unix:/tmp/serial-1.sock,server,nowait
-qmp unix:/tmp/qmp-1.sock,server,nowait
-display none
-daemonize


which follows the issue reported in the virtio-win project:
https://github.com/virtio-win/kvm-guest-drivers-windows/issues/1582


Thanks,
Al