arch/x86/kernel/umip.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/umip.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/umip.c- Extension
.c- Size
- 14101 bytes
- Lines
- 426
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/uaccess.hasm/umip.hasm/traps.hasm/insn.hasm/insn-eval.hlinux/ratelimit.h
Detected Declarations
function umip_printkfunction identify_insnfunction emulate_umip_insnfunction force_sig_info_umip_faultfunction fixup_umip_exception
Annotated Snippet
switch (X86_MODRM_REG(insn->modrm.value)) {
case 0:
/* The reg form of 0F 01 /0 encodes VMX instructions. */
if (X86_MODRM_MOD(insn->modrm.value) == 3)
return -EINVAL;
return UMIP_INST_SGDT;
case 1:
/*
* The reg form of 0F 01 /1 encodes MONITOR/MWAIT,
* STAC/CLAC, and ENCLS.
*/
if (X86_MODRM_MOD(insn->modrm.value) == 3)
return -EINVAL;
return UMIP_INST_SIDT;
case 4:
return UMIP_INST_SMSW;
default:
return -EINVAL;
}
} else if (insn->opcode.bytes[1] == 0x0) {
if (X86_MODRM_REG(insn->modrm.value) == 0)
return UMIP_INST_SLDT;
else if (X86_MODRM_REG(insn->modrm.value) == 1)
return UMIP_INST_STR;
else
return -EINVAL;
} else {
return -EINVAL;
}
}
/**
* emulate_umip_insn() - Emulate UMIP instructions and return dummy values
* @insn: Instruction structure with operands
* @umip_inst: A constant indicating the instruction to emulate
* @data: Buffer into which the dummy result is stored
* @data_size: Size of the emulated result
* @x86_64: true if process is 64-bit, false otherwise
*
* Emulate an instruction protected by UMIP and provide a dummy result. The
* result of the emulation is saved in @data. The size of the results depends
* on both the instruction and type of operand (register vs memory address).
* The size of the result is updated in @data_size. Caller is responsible
* of providing a @data buffer of at least UMIP_GDT_IDT_BASE_SIZE +
* UMIP_GDT_IDT_LIMIT_SIZE bytes.
*
* Returns:
*
* 0 on success, -EINVAL on error while emulating.
*/
static int emulate_umip_insn(struct insn *insn, int umip_inst,
unsigned char *data, int *data_size, bool x86_64)
{
if (!data || !data_size || !insn)
return -EINVAL;
/*
* These two instructions return the base address and limit of the
* global and interrupt descriptor table, respectively. According to the
* Intel Software Development manual, the base address can be 24-bit,
* 32-bit or 64-bit. Limit is always 16-bit. If the operand size is
* 16-bit, the returned value of the base address is supposed to be a
* zero-extended 24-byte number. However, it seems that a 32-byte number
* is always returned irrespective of the operand size.
*/
if (umip_inst == UMIP_INST_SGDT || umip_inst == UMIP_INST_SIDT) {
u64 dummy_base_addr;
u16 dummy_limit = 0;
/* SGDT and SIDT do not use registers operands. */
if (X86_MODRM_MOD(insn->modrm.value) == 3)
return -EINVAL;
if (umip_inst == UMIP_INST_SGDT)
dummy_base_addr = UMIP_DUMMY_GDT_BASE;
else
dummy_base_addr = UMIP_DUMMY_IDT_BASE;
/*
* 64-bit processes use the entire dummy base address.
* 32-bit processes use the lower 32 bits of the base address.
* dummy_base_addr is always 64 bits, but we memcpy the correct
* number of bytes from it to the destination.
*/
if (x86_64)
*data_size = UMIP_GDT_IDT_BASE_SIZE_64BIT;
else
*data_size = UMIP_GDT_IDT_BASE_SIZE_32BIT;
Annotation
- Immediate include surface: `linux/uaccess.h`, `asm/umip.h`, `asm/traps.h`, `asm/insn.h`, `asm/insn-eval.h`, `linux/ratelimit.h`.
- Detected declarations: `function umip_printk`, `function identify_insn`, `function emulate_umip_insn`, `function force_sig_info_umip_fault`, `function fixup_umip_exception`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.