arch/x86/virt/hw.c
Source file repositories/reference/linux-study-clean/arch/x86/virt/hw.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/virt/hw.c- Extension
.c- Size
- 9443 bytes
- Lines
- 374
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cpu.hlinux/cpumask.hlinux/errno.hlinux/kvm_types.hlinux/list.hlinux/percpu.hasm/perf_event.hasm/processor.hasm/virt.hasm/vmx.h
Detected Declarations
struct x86_virt_opsfunction x86_virt_register_emergency_callbackfunction x86_virt_unregister_emergency_callbackfunction x86_virt_invoke_kvm_emergency_callbackfunction x86_virt_cpu_vmxonfunction x86_vmx_enable_virtualization_cpufunction x86_vmx_disable_virtualization_cpufunction x86_vmx_emergency_disable_virtualization_cpufunction x86_vmx_exitfunction for_each_possible_cpufunction __x86_vmx_initfunction for_each_possible_cpufunction x86_vmx_initfunction x86_vmx_initfunction x86_vmx_exitfunction x86_svm_disable_virtualization_cpufunction x86_svm_emergency_disable_virtualization_cpufunction x86_svm_initfunction x86_svm_initfunction x86_virt_get_reffunction x86_virt_put_reffunction x86_virt_emergency_disable_virtualization_cpufunction x86_virt_init
Annotated Snippet
struct x86_virt_ops {
int feature;
int (*enable_virtualization_cpu)(void);
int (*disable_virtualization_cpu)(void);
void (*emergency_disable_virtualization_cpu)(void);
};
static struct x86_virt_ops virt_ops __ro_after_init;
__visible bool virt_rebooting;
EXPORT_SYMBOL_FOR_KVM(virt_rebooting);
static DEFINE_PER_CPU(int, virtualization_nr_users);
static cpu_emergency_virt_cb __rcu *kvm_emergency_callback;
void x86_virt_register_emergency_callback(cpu_emergency_virt_cb *callback)
{
if (WARN_ON_ONCE(rcu_access_pointer(kvm_emergency_callback)))
return;
rcu_assign_pointer(kvm_emergency_callback, callback);
}
EXPORT_SYMBOL_FOR_KVM(x86_virt_register_emergency_callback);
void x86_virt_unregister_emergency_callback(cpu_emergency_virt_cb *callback)
{
if (WARN_ON_ONCE(rcu_access_pointer(kvm_emergency_callback) != callback))
return;
rcu_assign_pointer(kvm_emergency_callback, NULL);
synchronize_rcu();
}
EXPORT_SYMBOL_FOR_KVM(x86_virt_unregister_emergency_callback);
static void x86_virt_invoke_kvm_emergency_callback(void)
{
cpu_emergency_virt_cb *kvm_callback;
/*
* RCU may not be watching the crashing CPU here, so rcu_dereference()
* triggers a suspicious-RCU-usage splat. In principle, a concurrent
* KVM module unload could race with this read; see commit 2baa33a8ddd6
* ("KVM: x86: Leave user-return notifier registered on reboot/shutdown")
* which notes that nothing prevents module unload during panic/reboot.
*
* However, taking a lock here would be riskier than the current race:
* the system is going down via NMI shootdown, and any lock could be
* held by an already-stopped CPU. Use rcu_dereference_raw() to silence
* the lockdep splat and accept the comically small remaining race;
* panic context inherently cannot guarantee complete correctness.
*/
kvm_callback = rcu_dereference_raw(kvm_emergency_callback);
if (kvm_callback)
kvm_callback();
}
#if IS_ENABLED(CONFIG_KVM_INTEL)
static DEFINE_PER_CPU(struct vmcs *, root_vmcs);
static int x86_virt_cpu_vmxon(void)
{
u64 vmxon_pointer = __pa(per_cpu(root_vmcs, raw_smp_processor_id()));
u64 msr;
cr4_set_bits(X86_CR4_VMXE);
asm goto("1: vmxon %[vmxon_pointer]\n\t"
_ASM_EXTABLE(1b, %l[fault])
: : [vmxon_pointer] "m"(vmxon_pointer)
: : fault);
return 0;
fault:
WARN_ONCE(1, "VMXON faulted, MSR_IA32_FEAT_CTL (0x3a) = 0x%llx\n",
rdmsrq_safe(MSR_IA32_FEAT_CTL, &msr) ? 0xdeadbeef : msr);
cr4_clear_bits(X86_CR4_VMXE);
return -EFAULT;
}
static int x86_vmx_enable_virtualization_cpu(void)
{
int r;
if (cr4_read_shadow() & X86_CR4_VMXE)
return -EBUSY;
intel_pt_handle_vmx(1);
r = x86_virt_cpu_vmxon();
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/cpumask.h`, `linux/errno.h`, `linux/kvm_types.h`, `linux/list.h`, `linux/percpu.h`, `asm/perf_event.h`, `asm/processor.h`.
- Detected declarations: `struct x86_virt_ops`, `function x86_virt_register_emergency_callback`, `function x86_virt_unregister_emergency_callback`, `function x86_virt_invoke_kvm_emergency_callback`, `function x86_virt_cpu_vmxon`, `function x86_vmx_enable_virtualization_cpu`, `function x86_vmx_disable_virtualization_cpu`, `function x86_vmx_emergency_disable_virtualization_cpu`, `function x86_vmx_exit`, `function for_each_possible_cpu`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.