diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c index f231863e8887..5572988ca3d4 100644 --- a/sys/compat/ndis/kern_windrv.c +++ b/sys/compat/ndis/kern_windrv.c @@ -311,6 +311,24 @@ windrv_unload(mod, img, len) #define WINDRV_LOADED htonl(0x42534F44) +#ifdef __amd64__ +static void +patch_user_shared_data_address(vm_offset_t img, size_t len) +{ + unsigned long i, n, max_addr, *addr; + + n = len - sizeof(unsigned long); + max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data); + for (i = 0; i < n; i++) { + addr = (unsigned long *)(img + i); + if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) { + *addr -= KI_USER_SHARED_DATA; + *addr += (unsigned long)&kuser_shared_data; + } + } +} +#endif + /* * Loader routine for actual Windows driver modules, ultimately * calls the driver's DriverEntry() routine. @@ -363,6 +381,10 @@ windrv_load(mod, img, len, bustype, devlist, regvals) return (ENOEXEC); } +#ifdef __amd64__ + patch_user_shared_data_address(img, len); +#endif + /* Dynamically link USBD.SYS -- optional */ if (pe_get_import_descriptor(img, &imp_desc, "USBD") == 0) { if (pe_patch_imports(img, "USBD", usbd_functbl)) diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h index ebe3f5dd2df2..769f93cd3727 100644 --- a/sys/compat/ndis/ntoskrnl_var.h +++ b/sys/compat/ndis/ntoskrnl_var.h @@ -605,6 +605,65 @@ struct kinterrupt { typedef struct kinterrupt kinterrupt; +struct ksystem_time { + uint32_t low_part; + int32_t high1_time; + int32_t high2_time; +}; + +enum nt_product_type { + NT_PRODUCT_WIN_NT = 1, + NT_PRODUCT_LAN_MAN_NT, + NT_PRODUCT_SERVER +}; + +enum alt_arch_type { + STANDARD_DESIGN, + NEC98x86, + END_ALTERNATIVES +}; + +struct kuser_shared_data { + uint32_t tick_count; + uint32_t tick_count_multiplier; + volatile struct ksystem_time interrupt_time; + volatile struct ksystem_time system_time; + volatile struct ksystem_time time_zone_bias; + uint16_t image_number_low; + uint16_t image_number_high; + int16_t nt_system_root[260]; + uint32_t max_stack_trace_depth; + uint32_t crypto_exponent; + uint32_t time_zone_id; + uint32_t large_page_min; + uint32_t reserved2[7]; + enum nt_product_type nt_product_type; + uint8_t product_type_is_valid; + uint32_t nt_major_version; + uint32_t nt_minor_version; + uint8_t processor_features[64]; + uint32_t reserved1; + uint32_t reserved3; + volatile uint32_t time_slip; + enum alt_arch_type alt_arch_type; + int64_t system_expiration_date; + uint32_t suite_mask; + uint8_t kdbg_enabled; + volatile uint32_t active_console; + volatile uint32_t dismount_count; + uint32_t com_plus_package; + uint32_t last_system_rit_event_tick_count; + uint32_t num_phys_pages; + uint8_t safe_boot_mode; + uint32_t trace_log; + uint64_t fill0; + uint64_t sys_call[4]; + union { + volatile struct ksystem_time tick_count; + volatile uint64_t tick_count_quad; + } tick; +}; + /* * In Windows, there are Physical Device Objects (PDOs) and * Functional Device Objects (FDOs). Physical Device Objects are @@ -1324,6 +1383,9 @@ struct drvdb_ent { }; extern image_patch_table ntoskrnl_functbl[]; +#ifdef __amd64__ +extern struct kuser_shared_data kuser_shared_data; +#endif typedef void (*funcptr)(void); typedef int (*matchfuncptr)(interface_type, void *, void *); @@ -1438,6 +1500,7 @@ extern void IoQueueWorkItem(io_workitem *, io_workitem_func, * routines live in the HAL. We try to imitate this behavior. */ #ifdef __i386__ +#define KI_USER_SHARED_DATA 0xffdf0000 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) #define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a) @@ -1447,6 +1510,7 @@ extern void IoQueueWorkItem(io_workitem *, io_workitem_func, #endif /* __i386__ */ #ifdef __amd64__ +#define KI_USER_SHARED_DATA 0xfffff78000000000UL #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 17ff3e536d25..80b1d984e5a3 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -121,6 +121,7 @@ typedef struct callout_entry callout_entry; static struct list_entry ntoskrnl_calllist; static struct mtx ntoskrnl_calllock; +struct kuser_shared_data kuser_shared_data; static struct list_entry ntoskrnl_intlist; static kspin_lock ntoskrnl_intlock; diff --git a/sys/compat/ndis/winx64_wrap.S b/sys/compat/ndis/winx64_wrap.S index c44fe053c8c2..3e5d994ab70b 100644 --- a/sys/compat/ndis/winx64_wrap.S +++ b/sys/compat/ndis/winx64_wrap.S @@ -125,26 +125,26 @@ x86_64_wrap_end: */ ENTRY(x86_64_call1) - subq $8,%rsp + subq $40,%rsp mov %rsi,%rcx call *%rdi - addq $8,%rsp + addq $40,%rsp ret ENTRY(x86_64_call2) - subq $24,%rsp + subq $40,%rsp mov %rsi,%rcx /* %rdx is already correct */ call *%rdi - addq $24,%rsp + addq $40,%rsp ret ENTRY(x86_64_call3) - subq $24,%rsp + subq $40,%rsp mov %rcx,%r8 mov %rsi,%rcx call *%rdi - addq $24,%rsp + addq $40,%rsp ret ENTRY(x86_64_call4) @@ -157,13 +157,13 @@ ENTRY(x86_64_call4) ret ENTRY(x86_64_call5) - subq $40,%rsp + subq $48,%rsp mov %r9,32(%rsp) mov %r8,%r9 mov %rcx,%r8 mov %rsi,%rcx call *%rdi - addq $40,%rsp + addq $48,%rsp ret ENTRY(x86_64_call6)