Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Nov 2010 11:55:51 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r215862 - stable/8/sys/compat/ndis
Message-ID:  <201011261155.oAQBtpQg038397@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Fri Nov 26 11:55:51 2010
New Revision: 215862
URL: http://svn.freebsd.org/changeset/base/215862

Log:
  MFC r215708:
  Resurrect amd64 support.
  - Many drivers on amd64 are picking system uptime, interrupt time and ticks
    via global data structure instead of calling functions for performance
    reasons. For now just patch such address so driver will not trigger page
    fault when trying to access such data. In future, additional callout may
    be added to update data in periodic intervals.
  - On amd64 we need to allocate "shadow space" on stack before calling any
    function.
  
  Submitted by:	Paul B Mahol <onemda at gmail.com>

Modified:
  stable/8/sys/compat/ndis/kern_windrv.c
  stable/8/sys/compat/ndis/ntoskrnl_var.h
  stable/8/sys/compat/ndis/subr_ntoskrnl.c
  stable/8/sys/compat/ndis/winx64_wrap.S
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/compat/ndis/kern_windrv.c
==============================================================================
--- stable/8/sys/compat/ndis/kern_windrv.c	Fri Nov 26 11:48:47 2010	(r215861)
+++ stable/8/sys/compat/ndis/kern_windrv.c	Fri Nov 26 11:55:51 2010	(r215862)
@@ -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, devl
 			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))

Modified: stable/8/sys/compat/ndis/ntoskrnl_var.h
==============================================================================
--- stable/8/sys/compat/ndis/ntoskrnl_var.h	Fri Nov 26 11:48:47 2010	(r215861)
+++ stable/8/sys/compat/ndis/ntoskrnl_var.h	Fri Nov 26 11:55:51 2010	(r215862)
@@ -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 
  * 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 
 #endif /* __i386__ */
 
 #ifdef __amd64__
+#define	KI_USER_SHARED_DATA 0xfffff78000000000UL
 #define	KeAcquireSpinLock(a, b)	*(b) = KfAcquireSpinLock(a)
 #define	KeReleaseSpinLock(a, b)	KfReleaseSpinLock(a, b)
 

Modified: stable/8/sys/compat/ndis/subr_ntoskrnl.c
==============================================================================
--- stable/8/sys/compat/ndis/subr_ntoskrnl.c	Fri Nov 26 11:48:47 2010	(r215861)
+++ stable/8/sys/compat/ndis/subr_ntoskrnl.c	Fri Nov 26 11:55:51 2010	(r215862)
@@ -121,6 +121,7 @@ typedef struct callout_entry callout_ent
 
 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;

Modified: stable/8/sys/compat/ndis/winx64_wrap.S
==============================================================================
--- stable/8/sys/compat/ndis/winx64_wrap.S	Fri Nov 26 11:48:47 2010	(r215861)
+++ stable/8/sys/compat/ndis/winx64_wrap.S	Fri Nov 26 11:55:51 2010	(r215862)
@@ -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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011261155.oAQBtpQg038397>