Cloud Agent kernel issue: AMX state corruption + unusable nested VMX

@nbradford — I think this needs someone from the Cloud Agents VM/kernel side.

I have a reproducible AMX state-corruption issue on a Cloud Agent. Linux x86 upstream tested the minimal reproducer for 100k trials without reproducing it and asked me to try an upstream guest kernel on the same Cursor infrastructure.

That experiment is currently blocked because nested KVM on the worker is not actually usable: KVM_CREATE_VM succeeds, but a minimal C program doing only KVM_CREATE_VCPU(0) causes the Cursor 6.12.94+ kernel to BUG in:

kvm_spurious_fault
alloc_loaded_vmcs
vmx_vcpu_create

I inspected the running kernel and the fault happens on VMCLEAR.

I’m not claiming the KVM issue causes the AMX issue — only that it prevents the upstream-kernel control test.

Could someone from the Cloud Agents infrastructure team either run the AMX repro on the same worker class with an upstream guest kernel, or provide the source/patchset/config for the 6.12.94+ guest kernel?

I have small standalone reproducers and full logs for both issues.

Hi there!

We detected that this may be a bug report, so we’ve moved your post to the Bug Reports category.

To help us investigate and fix this faster, could you edit your original post to include the details from the template below?

Bug Report Template - Click to expand

Where does the bug appear (feature/product)?

  • Editor, Tab & Chat (autocomplete, Composer, in-editor agent)
  • Terminal & commands
  • Models, pricing & API keys (availability, Auto/Max, BYOK/Bedrock)
  • MCP & tools
  • Cloud Agents & Automations (cursor.com/agents, scheduled/event)
  • BugBot & Code Review
  • Cursor CLI
  • Cursor Mobile
  • Remote (SSH / Dev Containers / WSL)
  • Account, billing & login
  • Something else…

Describe the Bug
A clear and concise description of what the bug is.


Steps to Reproduce
How can you reproduce this bug? We have a much better chance at fixing issues if we can reproduce them!

  1. …
  2. …
  3. …

Expected Behavior
What is meant to happen here that isn’t working correctly?


Screenshots / Screen Recordings
If applicable, attach images or videos (.jpg, .png, .gif, .mp4, .mov)


Operating System

  • Windows 10/11
  • MacOS
  • Linux

Version Information

  • For Cursor IDE: Menu → About Cursor → Copy
  • For Cursor CLI: Run agent about in your terminal
IDE:
Version: 2.xx.x
VSCode Version: 1.105.1
Commit: ......

CLI:
CLI Version 2026.01.17-d239e66

For AI issues: which model did you use?
Model name (e.g., Sonnet 4, Tab…)


For AI issues: add Request ID with privacy disabled
Request ID: f9a7046a-279b-47e5-ab48-6e8dc12daba1
For Background Agent issues, also post the ID: bc-…


Additional Information
Add any other context about the problem here.


Does this stop you from using Cursor?

  • Yes - Cursor is unusable
  • Sometimes - I can sometimes use Cursor
  • No - Cursor works, but with this issue

The more details you provide, the easier it is for us to reproduce and fix the issue. Thanks!

Where does the bug appear (feature/product)?

  • Cloud Agents & Automations

Describe the Bug

A Cursor Cloud Agent intermittently loses the contents of the Intel AMX TILEDATA registers across scheduling/blocking.

I reduced this to a small standalone C reproducer with no dependency on OpenVINO, oneDNN, Python, or any application code.

The program:

  1. requests AMX TILEDATA permission;
  2. loads a known non-zero pattern into all 8 AMX tile registers;
  3. performs a 1 ms nanosleep using a direct syscall;
  4. stores the tiles back and compares them with the original data.

On failing iterations, all 8192 bytes of TILEDATA come back as zero, while TILECFG is unchanged and the syscall succeeds.

There are no function calls while the AMX tiles are live. I verified the generated code with both GCC and Clang.

The same minimal reproducer was independently tested by a Linux x86 maintainer on upstream kernel configurations for 100,000 trials without a failure. Their recommendation was to test the same Cursor worker class with an upstream guest kernel.

The affected Cursor worker currently runs a custom 6.12.94+ guest kernel.


Steps to Reproduce

Save the attached amx_min.c, then:

gcc -O2 -g -Wall -Wextra -Werror -mamx-tile -fno-plt \
    amx_min.c -o amx_min

Run it on an allowed CPU:

timeout --kill-after=2s 20s taskset -c 0 ./amx_min

Control:

timeout --kill-after=2s 20s taskset -c 0 ./amx_min getpid

On this Cloud Agent, repeated runs produced:

GCC 13.3.0
nanosleep: 5/300, 5/300, 4/300 failures
getpid:    0/300, 0/300 failures

Clang 18.1.3
nanosleep: 3/300 failures
getpid:    0/300 failures

A typical failure is:

First mismatch: 8192/8192 bytes are zero; TILECFG unchanged

The failure is intermittent, so one clean run does not necessarily mean the environment is unaffected.

Under CPU contention it reproduces much more reliably; a separate test with no syscall in the live-tile interval also reproduces the loss.


Expected Behavior

AMX TILEDATA belonging to the process should be preserved when the process is scheduled out and resumed.

After nanosleep returns, the values stored from the AMX tiles should match the values loaded before the sleep.

They should not silently become zero.


Screenshots / Screen Recordings

Not applicable.

I can provide:

  • the minimal standalone C reproducer;
  • failing output and binary dumps;
  • disassembly from GCC and Clang;
  • the more extensive diagnostic suite;
  • the response from the Linux x86 maintainer who tested the reproducer upstream.

Operating System

  • Linux

Cloud Agent guest:

Linux cursor 6.12.94+
#1 SMP PREEMPT_DYNAMIC Mon Sep 7 16:15:06 UTC 2026 x86_64 GNU/Linux

CPU exposed to guest:

Intel Xeon
family 6, model 207, stepping 2
4 vCPUs
AMX_TILE / AMX_BF16 / AMX_INT8 exposed

Virtualization detected from the guest:

KVM
Firecracker

Version Information

This is a Cloud Agent infrastructure/kernel issue rather than an IDE or Cursor CLI issue.

Relevant guest environment:

Guest kernel: 6.12.94+
Kernel build: "#1 SMP PREEMPT_DYNAMIC Mon Sep 7 16:15:06 UTC 2026"
Architecture: x86_64
VMM visible from guest: Firecracker / KVM
Compiler reproductions:
  GCC: 13.3.0
  Clang: 18.1.3

For AI issues: which model did you use?

Not applicable. The issue reproduces in a standalone native C program and does not involve an AI model.


For AI issues: add Request ID with privacy disabled

Not applicable.


Additional Information

Linux x86 upstream tested the same minimal reproducer and reported 0 failures over 100,000 trials using:

  • a v7.2 guest kernel with a v6.12-based host kernel;
  • a v7.2 guest kernel with a vanilla v7.3-rc2 host kernel.

Their recommendation was to rerun the reproducer on the Cursor infrastructure with an upstream guest kernel to distinguish the Cursor custom guest kernel from the host/VMM.

I tried to perform that control experiment from inside the Cloud Agent, but nested KVM is not usable on this worker.

The environment exposes VMX and KVM:

CPUID.VMX=1
nested=Y
KVM_CREATE_VM succeeds
KVM_CAP_NESTED_STATE=8320

but a minimal program calling KVM_CREATE_VCPU(0) causes the Cursor guest kernel to BUG:

kernel BUG at arch/x86/kvm/x86.c:702
RIP: kvm_spurious_fault+0xe/0x10

alloc_loaded_vmcs+0x108/0x190
vmx_vcpu_create+0xa7/0x490
kvm_arch_vcpu_create
kvm_vm_ioctl_create_vcpu

I investigated this separately and localized the fault to VMCLEAR inside alloc_loaded_vmcs().

I am not claiming that this nested-KVM problem causes the AMX corruption. They may be unrelated. It only prevents me from running the upstream-guest-kernel control experiment requested by the Linux maintainer.

The most useful next step from the Cursor infrastructure side would therefore be either:

  1. run amx_min.c on the same Cloud Agent worker class with an upstream guest kernel (v6.12.94, current stable, or similar); or
  2. provide the exact source/patchset and .config used to build Cursor’s 6.12.94+ guest kernel.

That single comparison should tell us whether to investigate primarily the Cursor guest kernel or the host/VMM side.

I have standalone reproducers and full logs for both issues and am happy to provide anything useful for debugging.


Does this stop you from using Cursor?

  • No - Cursor works, but with this issue

It does not make Cursor itself unusable, but workloads using AMX can silently produce incorrect results on the affected Cloud Agent, which is considerably more serious than a crash for those workloads.

/*
 * Minimal KVM ioctl probe: open /dev/kvm, KVM_GET_API_VERSION,
 * KVM_CREATE_VM, KVM_CREATE_VCPU. Does not start a guest.
 *
 * One-shot diagnostic for Cursor Cloud Agent nested VMX.
 */
#include <errno.h>
#include <fcntl.h>
#include <linux/kvm.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

int main(void)
{
	int kvm, vm, vcpu;
	int api;

	printf("pid=%d\n", getpid());
	fflush(stdout);

	kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC);
	if (kvm < 0) {
		fprintf(stderr, "open(/dev/kvm) failed: %s\n", strerror(errno));
		return 1;
	}
	printf("open(/dev/kvm)=%d\n", kvm);
	fflush(stdout);

	api = ioctl(kvm, KVM_GET_API_VERSION, 0);
	if (api < 0) {
		fprintf(stderr, "KVM_GET_API_VERSION failed: %s\n", strerror(errno));
		return 1;
	}
	printf("KVM_GET_API_VERSION=%d (expected %d)\n", api, KVM_API_VERSION);
	fflush(stdout);

	printf("KVM_CAP_NR_VCPUS=%d\n", ioctl(kvm, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS));
	printf("KVM_CAP_NR_MEMSLOTS=%d\n", ioctl(kvm, KVM_CHECK_EXTENSION, KVM_CAP_NR_MEMSLOTS));
	printf("KVM_CAP_NESTED_STATE=%d\n", ioctl(kvm, KVM_CHECK_EXTENSION, KVM_CAP_NESTED_STATE));
	fflush(stdout);

	printf("calling KVM_CREATE_VM\n");
	fflush(stdout);
	vm = ioctl(kvm, KVM_CREATE_VM, 0);
	if (vm < 0) {
		fprintf(stderr, "KVM_CREATE_VM failed: %s\n", strerror(errno));
		return 2;
	}
	printf("KVM_CREATE_VM fd=%d SUCCESS\n", vm);
	fflush(stdout);

	printf("calling KVM_CREATE_VCPU(0) ioctl=0x%lx\n",
	       (unsigned long)KVM_CREATE_VCPU);
	fflush(stdout);

	vcpu = ioctl(vm, KVM_CREATE_VCPU, 0);
	if (vcpu < 0) {
		fprintf(stderr, "KVM_CREATE_VCPU failed: errno=%d %s\n",
			errno, strerror(errno));
		return 3;
	}
	printf("KVM_CREATE_VCPU fd=%d SUCCESS (unexpected on this host)\n", vcpu);
	fflush(stdout);
	return 0;
}
/* amx_min.c */
#define _GNU_SOURCE
#include <cpuid.h>
#include <errno.h>
#include <immintrin.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>

static _Alignas(64) unsigned char cfg[64], cfg_after[64];
static _Alignas(64) unsigned char src[8][1024], dst[8][1024];
static const struct timespec delay = { .tv_nsec = 1000000 };
#define TILES(OP) OP(0); OP(1); OP(2); OP(3); OP(4); OP(5); OP(6); OP(7)
#define LOAD(t) _tile_loadd(t, src[t], 64)
#define STORE(t) _tile_stored(t, dst[t], 64)

/* No function calls from LDTILECFG until TILERELEASE. */
__attribute__((noinline)) long roundtrip(long nr)
{
    _tile_loadconfig(cfg);
    TILES(LOAD);
    long ret;
    __asm__ volatile("syscall" : "=a"(ret)
        : "0"(nr), "D"(&delay), "S"(0L)
        : "rcx", "r11", "memory", "cc");
    _tile_storeconfig(cfg_after);
    for (int i = 0; i < 64; i++) {
        if (cfg[i] != ((volatile unsigned char *)cfg_after)[i]) {
            _tile_release();
            return -4096; /* Configuration changed; do not store tiles. */
        }
    }
    TILES(STORE);
    _mm_mfence();
    _tile_release();
    return ret;
}

int main(int argc, char **argv)
{
    if (argc > 2 || (argc == 2 && strcmp(argv[1], "getpid"))) {
        fprintf(stderr, "Usage: %s [getpid]\n", argv[0]);
        return 2;
    }
    unsigned a, b, c, d;
    if (!__get_cpuid_count(7, 0, &a, &b, &c, &d) || !(d & (1u << 24))) {
        puts("SKIP: AMX_TILE not exposed");
        return 77;
    }
    if (syscall(SYS_arch_prctl, 0x1023 /* ARCH_REQ_XCOMP_PERM */, 18L)) {
        perror("ARCH_REQ_XCOMP_PERM");
        return 77;
    }
    cfg[0] = 1;
    for (int t = 0; t < 8; t++) {
        cfg[16 + 2*t] = 64;
        cfg[48 + t] = 16;
        for (int i = 0; i < 1024; i++)
            src[t][i] = 1 + ((t*1024 + i) % 251);
    }
    int bad = 0;
    for (int n = 0; n < 300; n++) {
        memset(dst, 0xcc, sizeof dst);
        memset(cfg_after, 0xcc, sizeof cfg_after);
        long ret = roundtrip(argc == 2 ? SYS_getpid : SYS_nanosleep);
        if (ret == -4096) { puts("FAIL: TILECFG changed"); return 2; }
        if (ret < 0) { errno = (int)-ret; perror("syscall"); return 2; }
        if (memcmp(src, dst, sizeof src)) {
            if (bad++ == 0) {
                int zeros = 0;
                for (int t = 0; t < 8; t++)
                    for (int i = 0; i < 1024; i++) zeros += dst[t][i] == 0;
                printf("First mismatch: %d/8192 bytes are zero; TILECFG unchanged\n", zeros);
            }
        }
    }
    printf("%d/300 trials lost tile data (%s)\n", bad, argc == 2 ? "getpid" : "nanosleep");
    return bad ? 1 : 0;
}

kvm_create_vcpu.log (4,1 Ko)
amx_min.log (894 Octets)

Cloud Agent ID:

bc-a2a260f7-4ff1-4f06-aa36-ad281804e4d0

Approximate UTC times:

  • Main AMX investigation: 2026-09-09 around 18:31–18:33 UTC
  • KVM_CREATE_VCPU reproduction: 2026-09-10 around 21:19 UTC

The later reduced amx_min.c replay was performed on the same agent, but its exact per-command timestamp was not preserved, so I prefer not to guess one.

One clarification: I’m treating the AMX TILEDATA corruption and the nested-KVM kernel BUG as two separate issues. The second one matters here because it prevents me from running the upstream-guest-kernel control requested by the Linux x86 maintainer.

Hey @yoch_melka, thanks for the report, the reproducers, and the logs!

I reproduced both behaviors on our side.

  • For the AMX tile data: we compiled your amx_min.c unchanged and ran it on several Cloud Agent VMs. After the nanosleep the tiles intermittently come back as all zeros with TILECFG intact, exactly as you describe, and the getpid control never loses data. Our failure rate is actually higher than yours (roughly 90 to 120 of 300 trials on an 8 vCPU agent), so this is not specific to your agent.
  • For nested KVM: a minimal program that opens /dev/kvm, calls KVM_CREATE_VM and then KVM_CREATE_VCPU(0) hits the same kernel oops you reported, with the same call trace, on every Cloud Agent we tried. So the upstream guest kernel control test cannot be run from inside a Cloud Agent right now.

I’ve shared both cases with the team!

Has there been any movement on this? This would be absolutely fantastic to have fixed.

Also, this is what my Grok Bot had for details on the issue if it helps. Hopefully this is the right place to post it.

I believe I found the root cause of the nested KVM BUG (kvm_spurious_fault in alloc_loaded_vmcs / VMCLEAR), and I think there is a one-line fix.

Controlled test on one Cloud Agent VM (kernel 6.12.94+ built Sep 24, Intel family 6 model 207):

Cold boot, no snapshot restore: at 104 s uptime, KVM_CREATE_VCPU succeeded and an Android emulator booted with -accel on in 40 s (screencap ~1.2 s, uiautomator dump ~2.2 s).

Later the same VM was paused and restored. dmesg shows random: crng reseeded due to virtual machine fork at 1503 s.

After the restore, the same KVM_CREATE_VCPU hits kernel BUG at arch/x86/kvm/x86.c:702 (kvm_spurious_fault). The oops shows CR4.VMXE still set, so the guest still believes it is in VMX operation.

Sample: 14 fresh agents today. 13 were restored from a snapshot (the fork marker is on dmesg line 408, 5–27 s after boot). Every restored agent that used KVM hit the same BUG on the first KVM_CREATE_VCPU. The one cold-booted agent worked. Same CPU model and same kernel build in both groups, so the CPU is not the factor. The snapshot restore is.

Cause: the guest kernel has kvm.enable_virt_at_load=Y (visible in /sys/module/kvm/parameters), so it runs VMXON on every CPU at boot, before the template snapshot. The Firecracker snapshot/restore does not keep that nested VMX state, so after the restore the first VMX instruction (VMCLEAR) faults.

Suggested fix: add kvm.enable_virt_at_load=0 to the guest kernel command line. KVM then runs VMXON when /dev/kvm is first used, which is after the restore. The other option is to take template snapshots with no VMXON active.

Workarounds tried from inside the guest (none work):

CPU offline/online to force VMXOFF/VMXON: taking a CPU offline on a restored VM, with no KVM use at all, oopses and hangs the guest (this fits VMXOFF faulting for the same reason). cpu0 is not hot-pluggable.

The kernel has nomodule and no binder, so container Android (redroid) is not possible either.

Launching 8 agents at the same time did not produce a cold boot. All 8 were restored from the snapshot.

Impact: this blocks accelerated Android emulators in Cloud Agents. With the fix, agents could verify mobile apps end to end in their own VM, in parallel.

Hi! Any update of this?

It would unlock a big use case for us!