10 #define VIRTUAL_CS 0x08 11 #define VIRTUAL_DS 0x10 12 #define PHYSICAL_CS 0x18 13 #define PHYSICAL_DS 0x20 48 #define VIRTUAL(address) ( (address) - 0xffffffff00000000 ) 50 #define VIRTUAL(address) (address) 60 .macro virtcall
function 61 pushl $VIRTUAL(\
function)
68 #define UACCESS_PREFIX_librm 70 #define UACCESS_PREFIX_librm __librm_ 78 #define VIRT_CALL( function ) \ 79 "pushl $( " _S2 ( VIRTUAL ( function ) ) " )\n\t" \ 121 (
addr <= 0xffffffffUL ) )
174 int c,
size_t len ) {
185 int c,
size_t len ) {
196 extern char *
const data16;
197 extern char *
const text16;
199 #define __data16( variable ) \ 200 __attribute__ (( section ( ".data16" ) )) \ 201 _data16_ ## variable __asm__ ( #variable ) 203 #define __data16_array( variable, array ) \ 204 __attribute__ (( section ( ".data16" ) )) \ 205 _data16_ ## variable array __asm__ ( #variable ) 207 #define __bss16( variable ) \ 208 __attribute__ (( section ( ".bss16" ) )) \ 209 _data16_ ## variable __asm__ ( #variable ) 211 #define __bss16_array( variable, array ) \ 212 __attribute__ (( section ( ".bss16" ) )) \ 213 _data16_ ## variable array __asm__ ( #variable ) 215 #define __text16( variable ) \ 216 __attribute__ (( section ( ".text16.data" ) )) \ 217 _text16_ ## variable __asm__ ( #variable ) 219 #define __text16_array( variable, array ) \ 220 __attribute__ (( section ( ".text16.data" ) )) \ 221 _text16_ ## variable array __asm__ ( #variable ) 223 #define __use_data16( variable ) \ 224 ( * ( ( typeof ( _data16_ ## variable ) * ) \ 225 & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) 227 #define __use_text16( variable ) \ 228 ( * ( ( typeof ( _text16_ ## variable ) * ) \ 229 & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) ) 231 #define __from_data16( pointer ) \ 233 ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) ) 235 #define __from_text16( pointer ) \ 237 ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) ) 243 #define rm_cs __use_text16 ( rm_cs ) 245 #define rm_ds __use_text16 ( rm_ds ) 252 #define CODE_DEFAULT ".code64" 253 #define STACK_DEFAULT "q" 255 #define CODE_DEFAULT ".code32" 256 #define STACK_DEFAULT "l" 260 #define LINE_SYMBOL _S2 ( OBJECT ) "__line_" _S2 ( __LINE__ ) "__%=:" 263 #define TEXT16_CODE( asm_code_str ) \ 264 ".section \".text16\", \"ax\", @progbits\n\t" \ 265 "\n" LINE_SYMBOL "\n\t" \ 267 asm_code_str "\n\t" \ 268 CODE_DEFAULT "\n\t" \ 272 #define REAL_CODE( asm_code_str ) \ 273 "push" STACK_DEFAULT " $1f\n\t" \ 274 "call real_call\n\t" \ 275 TEXT16_CODE ( "\n1:\n\t" \ 281 #define PHYS_CODE( asm_code_str ) \ 282 "push" STACK_DEFAULT " $1f\n\t" \ 283 "call phys_call\n\t" \ 284 ".section \".text.phys\", \"ax\", @progbits\n\t"\ 285 "\n" LINE_SYMBOL "\n\t" \ 291 CODE_DEFAULT "\n\t" \ 346 #define IDTE_PRESENT 0x80 349 #define IDTE_TYPE_IRQ32 0x0e 352 #define IDTE_TYPE_IRQ64 0x0e 378 #define PUSH_INSN 0x50 381 #define MOVB_INSN 0xb0 384 #define JMP_INSN 0xe9 468 #define IO_PAGE_SIZE 0x200000UL 475 #define IO_BASE ( ( void * ) 0x100000000ULL ) 479 #define sipi __use_text16 ( sipi ) 486 #define sipi_ds __use_text16 ( sipi_ds )
static __always_inline int off_t userptr_t off_t second_off
static __always_inline size_t trivial_strlen_user(userptr_t buffer, off_t offset)
Find length of NUL-terminated string in user buffer.
static __always_inline void off_t int c
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define __text16_array(variable, array)
uint16_t mid
Middle 16 bits of address.
static __always_inline int trivial_memcmp_user(userptr_t first, off_t first_off, userptr_t second, off_t second_off, size_t len)
Compare data between user buffers.
uint8_t next[0]
Next instruction after jump.
uint32_t first
First block in range.
uint32_t vector
MSI-X vector.
static __always_inline void * trivial_user_to_virt(userptr_t userptr, off_t offset)
Convert user pointer to virtual address.
uint8_t intr
Interrupt number.
off_t memchr_user(userptr_t userptr, off_t offset, int c, size_t len)
Find character in user buffer.
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address)
uint16_t high
High 16 bits of address.
Page-level write-through.
uint8_t size
Entry size (in 32-bit words)
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
static __always_inline int off_t first_off
uint8_t attr
Type and attributes.
static __always_inline userptr_t trivial_userptr_add(userptr_t userptr, off_t offset)
Add offset to user pointer.
unsigned long long uint64_t
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
static __always_inline void trivial_memmove_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers, allowing for overlap.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
static __always_inline userptr_t UACCESS_INLINE(librm, phys_to_user)(unsigned long phys_addr)
Convert physical address to user pointer.
uint32_t high
High 32 bits of address.
Page-level cache disable.
static __always_inline off_t trivial_memchr_user(userptr_t buffer, off_t offset, int c, size_t len)
Find character in user buffer.
off_t userptr_sub(userptr_t userptr, userptr_t subtrahend)
Subtract user pointers.
struct i386_regs sipi_regs
Startup IPI register state.
A 32-bit interrupt descriptor table entry.
void memset_user(userptr_t userptr, off_t offset, int c, size_t len)
Fill user buffer with a constant byte.
static __always_inline void off_t userptr_t off_t size_t len
userptr_t userptr_add(userptr_t userptr, off_t offset)
Add offset to user pointer.
uint32_t userptr_t
A pointer to a user buffer.
uint8_t intr
Interrupt number.
static __always_inline void off_t userptr_t off_t src_off
uint8_t movb
"movb" instruction
Page is the last page in an allocation.
uint16_t low
Low 16 bits of address.
struct page_table __attribute__
#define __always_inline
Declare a function to be always inline.
A 32-bit interrupt descriptor table register.
static __always_inline void off_t userptr_t src
uint8_t push
"push" instruction
uint16_t low
Low 16 bits of address.
uint16_t copy_user_to_rm_stack(userptr_t data, size_t size)
Allocate space on the real-mode stack and copy data there from a user buffer.
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
char sipi_len[]
Length of startup IPI real-mode handler.
A 64-bit interrupt descriptor table entry.
static __always_inline void off_t dest_off
A 32-bit general register dump.
void setup_sipi(unsigned int vector, uint32_t handler, struct i386_regs *regs)
Set up startup IPI handler.
static __always_inline off_t trivial_userptr_sub(userptr_t userptr, userptr_t subtrahend)
Subtract user pointers.
size_t strlen_user(userptr_t userptr, off_t offset)
Find length of NUL-terminated string in user buffer.
32-bit interrupt wrapper stack frame
uint32_t reserved
Reserved.
int memcmp_user(userptr_t first, off_t first_off, userptr_t second, off_t second_off, size_t len)
Compare data between user buffers.
uint16_t segment
Code segment.
static __always_inline void trivial_memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define __text16(variable)
struct page_table io_pages
The I/O space page table.
void * user_to_virt(userptr_t userptr, off_t offset)
Convert user pointer to virtual address.
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
uint8_t data[48]
Additional event data.
const unsigned long virt_offset
uint32_t offset
Interrupt wrapper address offset.
void memmove_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers, allowing for overlap.
void remove_user_from_rm_stack(userptr_t data, size_t size)
Deallocate space on the real-mode stack, optionally copying back data to a user buffer.
Page is accessible by user code.
uint64_t page[512]
Page address and flags.
static __always_inline off_t userptr_t subtrahend
uint8_t jmp
"jmp" instruction
static __always_inline unsigned long off_t offset
Interrupt wrapper address offset.
static __always_inline userptr_t trivial_virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
static __always_inline int off_t userptr_t second
uint8_t attr
Type and attributes.
64-bit interrupt wrapper stack frame
A 64-bit interrupt descriptor table register.
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
uint16_t segment
Code segment.
static __always_inline void trivial_memset_user(userptr_t buffer, off_t offset, int c, size_t len)
Fill user buffer with a constant byte.