arch/x86/kernel/cpu/sgx/virt.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/sgx/virt.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/cpu/sgx/virt.c- Extension
.c- Size
- 11766 bytes
- Lines
- 455
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/kvm_types.hlinux/miscdevice.hlinux/mm.hlinux/mman.hlinux/sched/mm.hlinux/sched/signal.hlinux/slab.hlinux/xarray.hasm/sgx.huapi/asm/sgx.hencls.hsgx.h
Detected Declarations
struct sgx_vepcfunction __sgx_vepc_faultfunction sgx_vepc_faultfunction sgx_vepc_mmapfunction sgx_vepc_remove_pagefunction sgx_vepc_free_pagefunction sgx_vepc_remove_allfunction xa_for_eachfunction sgx_vepc_releasefunction xa_for_eachfunction __sgx_vepc_openfunction sgx_vepc_openfunction sgx_vepc_ioctlfunction sgx_vepc_initfunction sgx_virt_ecreatefunction __sgx_virt_einitfunction sgx_virt_einit
Annotated Snippet
static const struct file_operations sgx_vepc_fops = {
.owner = THIS_MODULE,
.open = sgx_vepc_open,
.unlocked_ioctl = sgx_vepc_ioctl,
.compat_ioctl = sgx_vepc_ioctl,
.release = sgx_vepc_release,
.mmap = sgx_vepc_mmap,
};
static struct miscdevice sgx_vepc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "sgx_vepc",
.nodename = "sgx_vepc",
.fops = &sgx_vepc_fops,
};
int __init sgx_vepc_init(void)
{
/* SGX virtualization requires KVM to work */
if (!cpu_feature_enabled(X86_FEATURE_VMX))
return -ENODEV;
INIT_LIST_HEAD(&zombie_secs_pages);
mutex_init(&zombie_secs_pages_lock);
return misc_register(&sgx_vepc_dev);
}
/**
* sgx_virt_ecreate() - Run ECREATE on behalf of guest
* @pageinfo: Pointer to PAGEINFO structure
* @secs: Userspace pointer to SECS page
* @trapnr: trap number injected to guest in case of ECREATE error
*
* Run ECREATE on behalf of guest after KVM traps ECREATE for the purpose
* of enforcing policies of guest's enclaves, and return the trap number
* which should be injected to guest in case of any ECREATE error.
*
* Return:
* - 0: ECREATE was successful.
* - <0: on error.
*/
int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs,
int *trapnr)
{
int ret;
/*
* @secs is an untrusted, userspace-provided address. It comes from
* KVM and is assumed to be a valid pointer which points somewhere in
* userspace. This can fault and call SGX or other fault handlers when
* userspace mapping @secs doesn't exist.
*
* Add a WARN() to make sure @secs is already valid userspace pointer
* from caller (KVM), who should already have handled invalid pointer
* case (for instance, made by malicious guest). All other checks,
* such as alignment of @secs, are deferred to ENCLS itself.
*/
if (WARN_ON_ONCE(!access_ok(secs, PAGE_SIZE)))
return -EINVAL;
__uaccess_begin();
ret = __ecreate(pageinfo, (void *)secs);
__uaccess_end();
if (encls_faulted(ret)) {
*trapnr = ENCLS_TRAPNR(ret);
return -EFAULT;
}
/* ECREATE doesn't return an error code, it faults or succeeds. */
WARN_ON_ONCE(ret);
return 0;
}
EXPORT_SYMBOL_FOR_KVM(sgx_virt_ecreate);
static int __sgx_virt_einit(void __user *sigstruct, void __user *token,
void __user *secs)
{
int ret;
/*
* Make sure all userspace pointers from caller (KVM) are valid.
* All other checks deferred to ENCLS itself. Also see comment
* for @secs in sgx_virt_ecreate().
*/
#define SGX_EINITTOKEN_SIZE 304
if (WARN_ON_ONCE(!access_ok(sigstruct, sizeof(struct sgx_sigstruct)) ||
!access_ok(token, SGX_EINITTOKEN_SIZE) ||
!access_ok(secs, PAGE_SIZE)))
Annotation
- Immediate include surface: `linux/kvm_types.h`, `linux/miscdevice.h`, `linux/mm.h`, `linux/mman.h`, `linux/sched/mm.h`, `linux/sched/signal.h`, `linux/slab.h`, `linux/xarray.h`.
- Detected declarations: `struct sgx_vepc`, `function __sgx_vepc_fault`, `function sgx_vepc_fault`, `function sgx_vepc_mmap`, `function sgx_vepc_remove_page`, `function sgx_vepc_free_page`, `function sgx_vepc_remove_all`, `function xa_for_each`, `function sgx_vepc_release`, `function xa_for_each`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.