Skip to content

Commit

Permalink
KVM: TDX: Add a method to ignore updating CPU dirty logging request f…
Browse files Browse the repository at this point in the history
…or TDs

Add a method to ignore requests to update CPU dirty logging for TDs, as
basic TDX does not support the PML feature, and KVM TDX does not allocate
or flush PML buffers for TDs.

Do not invoke vmx_update_cpu_dirty_logging() for TDs, and doing so would
cause a NULL pointer access error.

This is to fix the issue first reported in [1], where QEMU attaches an
emulated VGA device to a TD, resulting in a "kernel NULL pointer
dereference" in the host.

In QEMU, vga_common_init() sets the vram memory region to have a
dirty_log_mask with bit DIRTY_MEMORY_VGA.

pci_cirrus_vga_realize
  vga_common_init
    vga_dirty_log_start
      memory_region_set_log
       mr->dirty_log_mask = 1 << DIRTY_MEMORY_VGA;

QEMU's KVM acceleration code checks if mr->dirty_log_mask is non-zero
before setting the KVM_MEM_LOG_DIRTY_PAGES flag for the corresponding
memslot (which has no flag KVM_MEM_GUEST_MEMFD) in KVM.

This causes KVM to detect that a memslot has the KVM_MEM_LOG_DIRTY_PAGES
flag and invoke kvm_mmu_update_cpu_dirty_logging() -->
vmx_update_cpu_dirty_logging() to turn on PML, leading to the NULL pointer
access error.

Reported-by: ANAND NARSHINHA PATIL <[email protected]>
Reported-by: Pedro Principeza <[email protected]>
Reported-by: Farrah Chen <[email protected]>
Closes: canonical/tdx#202
Link: canonical/tdx#202 [1]
Signed-off-by: Yan Zhao <[email protected]>
  • Loading branch information
yanzhao56 authored and rpedgeco committed Jan 28, 2025
1 parent f197627 commit 31ed024
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion arch/x86/kvm/vmx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ static int vt_handle_exit(struct kvm_vcpu *vcpu,
return vmx_handle_exit(vcpu, fastpath);
}

static void vt_update_cpu_dirty_logging(struct kvm_vcpu *vcpu)
{
/*
* Basic TDX does not support feature PML. KVM does not enable PML in
* TD's VMCS, nor does it allocate or flush PML buffer for TDX.
*/
if (WARN_ON_ONCE(is_td_vcpu(vcpu)))
return;

vmx_update_cpu_dirty_logging(vcpu);
}

static int vt_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
if (unlikely(is_td_vcpu(vcpu)))
Expand Down Expand Up @@ -993,7 +1005,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
.handle_exit_irqoff = vmx_handle_exit_irqoff,

.cpu_dirty_log_size = PML_LOG_NR_ENTRIES,
.update_cpu_dirty_logging = vmx_update_cpu_dirty_logging,
.update_cpu_dirty_logging = vt_update_cpu_dirty_logging,

.nested_ops = &vmx_nested_ops,

Expand Down

0 comments on commit 31ed024

Please sign in to comment.