Index: /trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c	(revision 30189)
+++ /trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c	(revision 30190)
@@ -124,7 +124,9 @@
 #define	IS_KERNEL(v)	((uintptr_t)(v) >= kernelbase)
 
+#if 0
 static int vbi_verbose = 0;
 
 #define VBI_VERBOSE(msg) {if (vbi_verbose) cmn_err(CE_WARN, msg);}
+#endif
 
 /* Introduced in v6 */
@@ -212,6 +214,8 @@
 		 * actual number of CPUs running in the sytem.
 		 */
-		if (ncpus > VBI_NCPU)
+		if (ncpus > VBI_NCPU) {
+		    cmn_err(CE_NOTE, "cpu count mismatch.\n");
 			return (EINVAL);
+		}
 	} else {
 		use_old = 1;
@@ -219,5 +223,8 @@
 			use_old_with_ulong = 1;
 		else if (max_cpuid + 1 != VBI_NCPU)
+		{
+		    cmn_err(CE_NOTE, "cpuset_t size mismatch. probably too old a kernel.\n");
 			return (EINVAL);	/* cpuset_t size mismatch */
+		}
 	}
 
@@ -229,5 +236,5 @@
 			kobj_getsymvalue("contig_free", 1);
 		if (p_contig_free == NULL) {
-			cmn_err(CE_NOTE, " contig_free() not found in kernel");
+			cmn_err(CE_NOTE, " contig_free() not found in kernel\n");
 			return (EINVAL);
 		}
@@ -237,6 +244,5 @@
 	 * Check if this is S10 or Nevada
 	 */
-	if (!strncmp(utsname.release, "5.11", sizeof("5.11") - 1))
-	{
+	if (!strncmp(utsname.release, "5.11", sizeof("5.11") - 1)) {
 		/* Nevada detected... */
 		vbi_is_nevada = 1;
@@ -245,7 +251,5 @@
 		off_cpu_kprunrun = off_s11_cpu_kprunrun;
 		off_t_preempt = off_s11_t_preempt;
-	}
-	else
-	{
+	} else {
 		/* Solaris 10 detected... */
 		vbi_is_nevada = 0;
@@ -263,6 +267,5 @@
 	char krr = VBI_CPU_KPRUNRUN;
 	if (   (crr < 0 || crr > 1)
-		|| (krr < 0 || krr > 1))
-	{
+		|| (krr < 0 || krr > 1)) {
 		cmn_err(CE_NOTE, ":CPU structure sanity check failed! OS version mismatch.\n");
 		return EINVAL;
@@ -271,9 +274,9 @@
 	/* Thread */
 	char t_preempt = VBI_T_PREEMPT;
-	if (t_preempt < 0 || t_preempt > 32)
-	{
+	if (t_preempt < 0 || t_preempt > 32) {
 		cmn_err(CE_NOTE, ":Thread structure sanity check failed! OS version mismatch.\n");
 		return EINVAL;
 	}
+
 	return (0);
 }
@@ -335,5 +338,5 @@
 
 	if (ptr == NULL) {
-		VBI_VERBOSE("vbi_internal_alloc() failure");
+		cmn_err(CE_NOTE, "vbi_internal_alloc() failure for %lu bytes", size);
 		return (NULL);
 	}
@@ -366,5 +369,5 @@
 
 	if ((pa & PAGEOFFSET) || (size & PAGEOFFSET)) {
-		VBI_VERBOSE("vbi_kernel_map() bad pa or size");
+		cmn_err(CE_NOTE, "vbi_kernel_map() bad pa (0x%lx) or size (%lu)", pa, size);
 		return (NULL);
 	}
@@ -682,5 +685,5 @@
 			(caddr_t)addr, len, F_SOFTLOCK, access);
 		if (err != 0) {
-			VBI_VERBOSE("vbi_lock_va() failed to lock");
+			cmn_err(CE_NOTE, "vbi_lock_va() failed to lock");
 			return (-1);
 		}
@@ -733,5 +736,4 @@
 	struct segvbi_data *data;
 	struct as *as = seg->s_as;
-	int error = 0;
 	caddr_t va;
 	ulong_t pgcnt;
@@ -756,5 +758,5 @@
 	}
 
-	return (error);
+	return (0);
 }
 
@@ -801,5 +803,7 @@
 
 /*
- * We never demand-fault for seg_vbi.
+ * We would demand fault if the (u)read() path would SEGOP_FAULT()
+ * on buffers mapped in via vbi_user_map() i.e. prefaults before DMA.
+ * Don't fail in such case where we're called directly, see #5047.
  */
 static int
@@ -807,5 +811,5 @@
 	enum fault_type type, enum seg_rw rw)
 {
-	return (FC_MAKE_ERR(EFAULT));
+	return (0);
 }
 
@@ -862,5 +866,14 @@
 {
 	struct segvbi_data *data = seg->s_data;
-	return (data->prot);
+	size_t pgno = seg_page(seg, addr + len) - seg_page(seg, addr) + 1;
+	if (pgno != 0)
+	{
+	    do
+	    {
+	        pgno--;
+	        protv[pgno] = data->prot;
+	    } while (pgno != 0);
+	}
+	return (0);
 }
 
@@ -977,5 +990,5 @@
 		error = ENOMEM;
 	if (error)
-		VBI_VERBOSE("vbi_user_map() failed");
+		cmn_err(CE_NOTE, "vbi_user_map() failed error=%d", error);
 	as_rangeunlock(as);
 	return (error);
