aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2026-02-10 17:21:32 +0100
committerAlexander Potapenko <glider@google.com>2026-02-11 07:33:38 +0000
commit5f58a1979fcf122ff2115a2d83857e75fd0d6260 (patch)
tree126ae7ef3dab8170b85f37e24dd7522b5069a224 /executor
parentc96f11a3a42272152e5af9b801a32490748f1f7e (diff)
executor: minor uexit changes in guest_main() for amd64
Use UEXIT_END to indicate normal guest termination, and UEXIT_INVALID_MAIN to indicate malformed guest program.
Diffstat (limited to 'executor')
-rw-r--r--executor/common_kvm_amd64_syzos.h38
1 files changed, 14 insertions, 24 deletions
diff --git a/executor/common_kvm_amd64_syzos.h b/executor/common_kvm_amd64_syzos.h
index 99e881b73..9ff5af6d0 100644
--- a/executor/common_kvm_amd64_syzos.h
+++ b/executor/common_kvm_amd64_syzos.h
@@ -172,6 +172,7 @@ typedef enum {
UEXIT_END = (uint64)-1,
UEXIT_IRQ = (uint64)-2,
UEXIT_ASSERT = (uint64)-3,
+ UEXIT_INVALID_MAIN = (uint64)-4,
} uexit_code;
typedef enum {
@@ -183,7 +184,10 @@ __attribute__((naked))
GUEST_CODE static void
dummy_null_handler()
{
- asm("iretq");
+ asm volatile(R"(
+ movq $-2, %%rdi
+ call guest_uexit
+ )" ::: "memory", "rdi", "cc");
}
__attribute__((naked)) GUEST_CODE static void uexit_irq_handler()
@@ -223,11 +227,11 @@ guest_main(uint64 cpu)
while (size >= sizeof(struct api_call_header)) {
struct api_call_header* cmd = (struct api_call_header*)addr;
- if (cmd->call >= SYZOS_API_STOP)
- return;
- if (cmd->size > size)
- return;
volatile uint64 call = cmd->call;
+ if ((call >= SYZOS_API_STOP) || (cmd->size > size)) {
+ guest_uexit(UEXIT_INVALID_MAIN);
+ return;
+ }
if (call == SYZOS_API_UEXIT) {
// Issue a user exit.
struct api_call_uexit* ucmd = (struct api_call_uexit*)cmd;
@@ -312,7 +316,7 @@ guest_main(uint64 cpu)
addr += cmd->size;
size -= cmd->size;
};
- guest_uexit((uint64)-1);
+ guest_uexit(UEXIT_END);
}
GUEST_CODE static noinline void guest_execute_code(uint8* insns, uint64 size)
@@ -838,24 +842,10 @@ GUEST_CODE static noinline void setup_l2_page_tables(cpu_vendor_id vendor, uint6
} else if (r.gpa == X86_SYZOS_ADDR_STACK_BOTTOM) {
// Map stack to the VM's dedicated stack buffer
backing = X86_SYZOS_ADDR_VM_STACK(cpu_id, vm_id);
- } else if (r.gpa == X86_SYZOS_ADDR_ZERO ||
- r.gpa == X86_SYZOS_ADDR_VAR_IDT ||
- r.gpa == X86_SYZOS_ADDR_BOOT_ARGS ||
- r.gpa == X86_SYZOS_ADDR_PT_POOL ||
- r.gpa == X86_SYZOS_ADDR_VAR_TSS) {
- // Critical System Regions: Allocate and COPY from L1.
- // We must copy the PT POOL because the PD entries in ADDR_ZERO
- // point to tables allocated here. If we don't copy, L2 sees
- // empty page tables and cannot resolve addresses like 0x50000.
- // GDT/IDT/TSS/BootArgs are also copied for valid environment.
- backing = guest_alloc_page();
- guest_memcpy((void*)backing, (void*)gpa, KVM_PAGE_SIZE);
- } else if (r.flags & MEM_REGION_FLAG_EXECUTOR_CODE) {
- // Identity map the Executor Code.
- backing = gpa;
} else {
- // Allocate new backing memory
- backing = guest_alloc_page();
+ // Identity map all other regions to prevent L1 OOM exhaustion.
+ // The L2 guest is transient and does not need duplicates of L1's GDT/IDT/TSS/Heap.
+ backing = gpa;
}
l2_map_page(cpu_id, vm_id, gpa, backing, flags);
}
@@ -1194,7 +1184,7 @@ GUEST_CODE static noinline void init_vmcs_host_state(void)
vmwrite(VMCS_HOST_TR_SELECTOR, X86_SYZOS_SEL_TSS64);
// Base addresses.
- vmwrite(VMCS_HOST_TR_BASE, 0);
+ vmwrite(VMCS_HOST_TR_BASE, X86_SYZOS_ADDR_VAR_TSS);
vmwrite(VMCS_HOST_GDTR_BASE, X86_SYZOS_ADDR_GDT);
vmwrite(VMCS_HOST_IDTR_BASE, X86_SYZOS_ADDR_VAR_IDT);
vmwrite(VMCS_HOST_FS_BASE, rdmsr(X86_MSR_FS_BASE));