--- a/config/hal.c	Fri Feb 20 12:38:27 2015
+++ b/config/hal.c	Fri Feb 20 12:39:43 2015
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2007 Daniel Stone
  * Copyright © 2007 Red Hat, Inc.
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -152,7 +152,7 @@
     char *ptr;
     char disppath[PATH_MAX];
 
-    if ((num_session_disp_dev == num_total_disp_dev) || !disp_dev_path[0])
+    if (((num_session_disp_dev & 0xFF) == num_total_disp_dev) || !disp_dev_path[0])
 	return FALSE;
 
     if (lstat(path, &statbuf) == 0 &&
@@ -544,7 +544,7 @@
     }
 
 #if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
-    if ((num_session_disp_dev < num_total_disp_dev) &&
+    if ((num_session_disp_dev < (num_total_disp_dev & 0x0FF)) &&
 		(!strcmp(name, "keyboard") || !strcmp(name, "mouse"))) {
 	int i;
 
--- a/hw/xfree86/common/xf86AutoConfig.c	Fri Feb 20 12:24:38 2015
+++ b/hw/xfree86/common/xf86AutoConfig.c	Fri Feb 20 12:36:48 2015
@@ -1,6 +1,7 @@
 /*
  * Copyright 2003 by David H. Dawes.
  * Copyright 2003 by X-Oz Technologies.
+ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All Rights Reserved.
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -50,6 +51,11 @@
 #include <ctype.h>
 #endif
 
+#if (defined(__sparc__) || defined(__sparc))
+static Bool MultiSessionConfig (void);
+extern int num_total_disp_dev;
+#endif
+
 /* Sections for the default built-in configuration. */
 
 #define BUILTIN_DEVICE_NAME \
@@ -168,6 +174,11 @@
     char buf[1024];
     ConfigStatus ret;
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+    /* Do not do MultiSessionConfig() when invoked with -isolateDevice option */
+    if ((num_total_disp_dev & 0x1000)|| !MultiSessionConfig()) {
+#endif
+
     listPossibleVideoDrivers(deviceList, 20);
 
     for (p = deviceList; *p; p++) {
@@ -196,6 +207,10 @@
         free(*p);
     }
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+    }
+#endif
+
     xf86MsgVerb(X_DEFAULT, 0,
                 "Using default built-in configuration (%d lines)\n",
                 builtinLines);
@@ -448,3 +403,176 @@
 
     return ptr;
 }
+
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+#include <libdevinfo.h>
+#include <xorg/xf86Pci.h>
+#include "pciaccess.h"
+#include <sys/utsname.h>
+
+#define MAX_DEV                        16
+
+#define IS_VGA(c) \
+       (((c) & 0x00ffff00) \
+       == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
+
+
+#define BUILTIN_MULTI_SERVERFLAGS_OPT1 \
+       "\tOption\t\"DefaultServerLayout\"\t\"Xsession0\"\n"
+
+#define BUILTIN_MULTI_SECTION_POST \
+       "EndSection\n\n"
+
+#define BUILTIN_MULTI_SERVERFLAGS_OPT2 \
+       "\tOption\t\"AutoAddDevices\"\t\"true\"\n"
+
+#define BUILTIN_MULTI_SERVERFLAGS_SECTION \
+       "Section \"ServerFlags\"\n" \
+       BUILTIN_MULTI_SERVERFLAGS_OPT1 \
+       BUILTIN_MULTI_SERVERFLAGS_OPT2 \
+       BUILTIN_MULTI_SECTION_POST
+
+#define BUILTIN_MULTI_LAYOUT_SECTION_PRE \
+       "Section \"ServerLayout\"\n" \
+       "\tIdentifier\t\"Xsession%d\"\n"
+
+#define BUILTIN_MULTI_LAYOUT_SECTION_LINE \
+       "\tScreen\t\t\"Screen%d\"\n"
+
+#define BUILTIN_MULTI_SCREEN_SECTION_PRE \
+       "Section \"Screen\"\n" \
+       "\tIdentifier\t\"Screen%d\"\n"
+
+#define BUILTIN_MULTI_SCREEN_SECTION_LINE \
+       "\tDevice\t\t\"Card%d\"\n"
+
+#define BUILTIN_MULTI_DEVICE_SECTION_PRE \
+       "Section \"Device\"\n" \
+       "\tIdentifier\t\"Card%d\"\n"
+
+#define BUILTIN_MULTI_DEVICE_SECTION_LINE \
+       "\tBusID\t\t\"%s\"\n\tDriver\t\t\"%s\"\n"
+
+static Bool
+MultiSessionConfig (void)
+{
+    di_node_t node;
+    struct pci_device_iterator * iter;
+    struct pci_device * dev;
+    typedef struct {
+       char            busid[64];
+       char            dev_path[PATH_MAX];
+    } disp_dev_type;
+    disp_dev_type disp_dev[MAX_DEV];
+    int num = 0;
+    char buf[1024];
+    int i;
+    struct utsname sys;
+    struct sol_device_private {
+        struct pci_device  base;
+        const char * device_string;
+    };
+#define DEV_PATH(dev)    (((struct sol_device_private *) dev)->device_string)
+
+    if (uname(&sys) < 0) {
+       xf86Msg(X_ERROR, "Error in uname call\n");
+       return FALSE;
+    }
+
+    if (strcmp(sys.machine, "sun4v"))
+       return FALSE;
+
+    iter = pci_slot_match_iterator_create( NULL );
+
+    while ( (dev = pci_device_next( iter )) != NULL ) {
+       if (IS_VGA(dev->device_class)) {
+           if (num > MAX_DEV) {
+               xf86Msg(X_ERROR, "Too many display devices: %d\n", num);
+               return FALSE;
+           }
+
+           memset(&disp_dev[num], 0, sizeof (disp_dev_type));
+
+           snprintf(disp_dev[num].busid, sizeof(disp_dev[num].busid),
+               "PCI:%d@%d:%d:%d", dev->bus, dev->domain,
+               dev->dev, dev->func);
+
+           strcpy(disp_dev[num].dev_path, "/devices");
+           strncat(disp_dev[num].dev_path, DEV_PATH(dev),
+               sizeof(disp_dev_type) - strlen("/devices"));
+
+           num++;
+       }
+    }
+
+    pci_iterator_destroy(iter);
+
+    /* Do not do multi-session configuration if dev number is 0 or 1 */
+    if (num <= 1)
+       return FALSE;
+
+    snprintf(buf, sizeof(buf), BUILTIN_MULTI_SERVERFLAGS_SECTION);
+    AppendToConfig(buf);
+
+    for (i = 0; i < num; i++) {
+       char drv[32];
+
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_LAYOUT_SECTION_PRE, i);
+       AppendToConfig(buf);
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_LAYOUT_SECTION_LINE, i);
+       AppendToConfig(buf);
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_SECTION_POST);
+       AppendToConfig(buf);
+
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_SCREEN_SECTION_PRE, i);
+       AppendToConfig(buf);
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_SCREEN_SECTION_LINE, i);
+       AppendToConfig(buf);
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_SECTION_POST);
+       AppendToConfig(buf);
+
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_DEVICE_SECTION_PRE, i);
+       AppendToConfig(buf);
+
+       drv[0] = 0;
+       if (disp_dev[i].dev_path) {
+           int iret;
+           int fd;
+
+
+           fd = open(disp_dev[i].dev_path, O_RDONLY);
+           if (fd >= 0) {
+               struct vis_identifier visid;
+               const char *cp;
+
+               SYSCALL(iret = ioctl(fd, VIS_GETIDENTIFIER, &visid));
+               close (fd);
+
+               if (iret >= 0) {
+                   if (strcmp(visid.name, "SUNWtext") != 0) {
+                       for (cp = visid.name; (*cp != '\0') && isupper((uchar_t)*cp); cp++);
+                       /* find end of all uppercase vendor section */
+                       if ((cp != visid.name) && (*cp != '\0'))
+                           strncpy (drv, cp, sizeof(drv));
+                   }
+               }
+           }
+        }
+
+       if (drv[0] == 0) {
+           xf86Msg(X_ERROR, "Can't find driver for session %d\n", i);
+           FreeConfig();
+           return FALSE;
+       }
+
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_DEVICE_SECTION_LINE,
+               disp_dev[i].busid, drv);
+       AppendToConfig(buf);
+       snprintf(buf, sizeof(buf), BUILTIN_MULTI_SECTION_POST);
+      AppendToConfig(buf);
+    }
+
+    return TRUE;
+}
+#endif
+
--- a/hw/xfree86/common/xf86pciBus.c	Wed May 20 08:27:14 2015
+++ b/hw/xfree86/common/xf86pciBus.c	Wed May 20 08:28:57 2015
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -131,6 +131,27 @@
     }
     free(iter);
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+    /*
+     * num_total_disp_dev does not reflect accurate number of display
+     * device when xf86IsolateDevice is set, redo it.
+     */
+    if (xf86IsolateDevice.domain != PCI_MATCH_ANY) {
+       num_total_disp_dev = 0x1000;
+
+       iter = pci_slot_match_iterator_create (NULL);
+       while ((info = pci_device_next(iter)) != NULL) {
+           if (PCIINFOCLASSES(info->device_class)) {
+               pci_device_probe(info);
+
+               if (IS_VGA(info->device_class))
+                   num_total_disp_dev++;
+           }
+       }
+    }
+    free(iter);
+#endif
+
     /* If we haven't found a primary device try a different heuristic */
     if (primaryBus.type == BUS_NONE && num) {
         for (i = 0; i < num; i++) {
@@ -1219,7 +1240,11 @@
 #ifdef __linux__
         driverList[idx++] = "nouveau";
 #endif
+#ifdef sun
+        driverList[idx++] = "nvidia";
+#else
         driverList[idx++] = "nv";
+#endif
         break;
     }
     case 0x1106:
--- a/hw/xfree86/common/xf86Xinput.c	Fri Feb 20 12:34:32 2015
+++ b/hw/xfree86/common/xf86Xinput.c	Fri Feb 20 12:37:40 2015
@@ -46,7 +46,7 @@
  * authorization from the copyright holder(s) and author(s).
  */
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All Rights Reserved.
  */
 
 #ifdef HAVE_XORG_CONFIG_H
@@ -1502,7 +1502,7 @@
     }
 
 #if ((defined(__sparc__) || defined(__sparc)) && defined(sun))
-    if (num_session_disp_dev < num_total_disp_dev) {
+    if (num_session_disp_dev < (num_total_disp_dev & 0x0FFF)) {
 	int i;
 
 	for (i = 0; i < MAX_DEVICES; i++) {
--- a/hw/xfree86/common/xf86Bus.c	Fri Feb 20 12:25:35 2015
+++ b/hw/xfree86/common/xf86Bus.c	Fri Feb 20 12:26:02 2015
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -207,9 +208,6 @@
 #ifdef XSERVER_LIBPCIACCESS
     xf86PciProbe();
 #endif
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-    xf86SbusProbe();
-#endif
 #ifdef XSERVER_PLATFORM_BUS
     xf86platformPrimary();
 #endif
--- a/hw/xfree86/common/xf86AutoConfig.c	2017-02-01 15:25:17.530888588 -0800
+++ b/hw/xfree86/common/xf86AutoConfig.c	2017-02-01 15:26:39.121379814 -0800
@@ -253,66 +253,7 @@
 #ifdef XSERVER_PLATFORM_BUS
     i = xf86PlatformMatchDriver(matches, nmatches);
 #endif
-#ifdef __sun
-    /* Check for driver type based on /dev/fb type and if valid, use
-       it instead of PCI bus probe results */
-    if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
-        struct vis_identifier visid;
-        const char *cp;
-        int iret;
 
-        SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
-        if (iret < 0) {
-            int fbfd;
-
-            fbfd = open(xf86SolarisFbDev, O_RDONLY);
-            if (fbfd >= 0) {
-                SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
-                close(fbfd);
-            }
-        }
-
-        if (iret < 0) {
-            xf86Msg(X_WARNING,
-                    "could not get frame buffer identifier from %s\n",
-                    xf86SolarisFbDev);
-        }
-        else {
-            xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
-
-            /* Special case from before the general case was set */
-            if (strcmp(visid.name, "NVDAnvda") == 0) {
-                matches[i++] = xnfstrdup("nvidia");
-            }
-
-            /* General case - split into vendor name (initial all-caps
-               prefix) & driver name (rest of the string). */
-            if (strcmp(visid.name, "SUNWtext") != 0) {
-                for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
-                    /* find end of all uppercase vendor section */
-                }
-                if ((cp != visid.name) && (*cp != '\0')) {
-                    char *driverName = xnfstrdup(cp);
-                    char *vendorName = xnfstrdup(visid.name);
-
-                    vendorName[cp - visid.name] = '\0';
-
-                    matches[i++] = vendorName;
-                    matches[i++] = driverName;
-                }
-            }
-        }
-    }
-#endif
-#ifdef __sparc__
-    if (i < (nmatches - 1))
-    {
-        char *sbusDriver = sparcDriverName();
-
-        if (sbusDriver)
-            matches[i++] = xnfstrdup(sbusDriver);
-    }
-#endif
 #ifdef XSERVER_LIBPCIACCESS
     if (i < (nmatches - 1))
         i += xf86PciMatchDriver(&matches[i], nmatches - i);
