rpms/kernel/devel linux-2.6-ahci-export-capabilities.patch, NONE, 1.2.2.2 linux-2.6-nfs4-ver4opt.patch, NONE, 1.2.2.2 linux-2.6-rfkill-all.patch, NONE, 1.1.2.2 linux-2.6-rtc-show-hctosys.patch, NONE, 1.1.2.2 linux-2.6-scsi-sd-fix-oops-during-scanning.patch, NONE, 1.1.2.1 linux-2.6-scsi-sg-fix-oops-in-error-path.patch, NONE, 1.1.2.1 linux-2.6.31-modules-ro-nx.patch, NONE, 1.2.2.2 linux-2.6.31-nx-data.patch, NONE, 1.1.2.2 drm-nouveau.patch, 1.8.6.17, 1.8.6.18 kernel.spec, 1.1294.2.65, 1.1294.2.66 xen.pvops.patch, 1.1.2.41, 1.1.2.42

myoung myoung at fedoraproject.org
Tue Sep 15 19:45:56 UTC 2009


Author: myoung

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv2816

Modified Files:
      Tag: private-myoung-dom0-branch
	drm-nouveau.patch kernel.spec xen.pvops.patch 
Added Files:
      Tag: private-myoung-dom0-branch
	linux-2.6-ahci-export-capabilities.patch 
	linux-2.6-nfs4-ver4opt.patch linux-2.6-rfkill-all.patch 
	linux-2.6-rtc-show-hctosys.patch 
	linux-2.6-scsi-sd-fix-oops-during-scanning.patch 
	linux-2.6-scsi-sg-fix-oops-in-error-path.patch 
	linux-2.6.31-modules-ro-nx.patch linux-2.6.31-nx-data.patch 
Log Message:
switch pvops to F-12 branch for the moment


linux-2.6-ahci-export-capabilities.patch:
 ahci.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

--- NEW FILE linux-2.6-ahci-export-capabilities.patch ---
commit 489b070aa53cb6a70494f53d9d8bd4c8570439e4
Author: Matthew Garrett <mjg at redhat.com>
Date:   Fri Jul 17 20:06:06 2009 +0100

    libata: Export AHCI capabilities
    
    AHCI exports various capability bits that may be of interest to userspace
    such as whether the BIOS claims a port is hotpluggable or eSATA. Providing
    these via sysfs along with the version of the AHCI spec implemented by
    the host allows userspace to make policy decisions for things like ALPM.
    
    Signed-off-by: Matthew Garrett <mjg at redhat.com>

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 336eb1e..5a5c160 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -327,10 +327,24 @@ static ssize_t ahci_activity_store(struct ata_device *dev,
 				   enum sw_activity val);
 static void ahci_init_sw_activity(struct ata_link *link);
 
+static ssize_t ahci_show_host_caps(struct device *dev,
+				   struct device_attribute *attr, char *buf);
+static ssize_t ahci_show_host_version(struct device *dev,
+				      struct device_attribute *attr, char *buf);
+static ssize_t ahci_show_port_cmd(struct device *dev,
+				  struct device_attribute *attr, char *buf);
+
+DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
+DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
+DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
+
 static struct device_attribute *ahci_shost_attrs[] = {
 	&dev_attr_link_power_management_policy,
 	&dev_attr_em_message_type,
 	&dev_attr_em_message,
+	&dev_attr_ahci_host_caps,
+	&dev_attr_ahci_host_version,
+	&dev_attr_ahci_port_cmd,
 	NULL
 };
 
@@ -696,6 +710,36 @@ static void ahci_enable_ahci(void __iomem *mmio)
 	WARN_ON(1);
 }
 
+static ssize_t ahci_show_host_caps(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ata_port *ap = ata_shost_to_port(shost);
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+
+	return sprintf(buf, "%x\n", hpriv->cap);
+}
+
+static ssize_t ahci_show_host_version(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ata_port *ap = ata_shost_to_port(shost);
+	void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+
+	return sprintf(buf, "%x\n", readl(mmio + HOST_VERSION));
+}
+
+static ssize_t ahci_show_port_cmd(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ata_port *ap = ata_shost_to_port(shost);
+	void __iomem *port_mmio = ahci_port_base(ap);
+
+	return sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD));
+}
+
 /**
  *	ahci_save_initial_config - Save and fixup initial config values
  *	@pdev: target PCI device

linux-2.6-nfs4-ver4opt.patch:
 fs/nfs/internal.h    |   10 +-
 fs/nfs/super.c       |  214 ++++++++++++++++++++++++++++++++++-----------------
 include/linux/nfs4.h |    1 
 3 files changed, 155 insertions(+), 70 deletions(-)

--- NEW FILE linux-2.6-nfs4-ver4opt.patch ---
diff -up linux-2.6.30.i686/fs/nfs/internal.h.save linux-2.6.30.i686/fs/nfs/internal.h
--- linux-2.6.30.i686/fs/nfs/internal.h.save	2009-09-10 10:14:10.000000000 -0400
+++ linux-2.6.30.i686/fs/nfs/internal.h	2009-09-10 11:06:38.000000000 -0400
@@ -49,6 +49,11 @@ struct nfs_clone_mount {
 #define NFS_MAX_SECFLAVORS	(12)
 
 /*
+ * Value used if the user did not specify a port value.
+ */
+#define NFS_UNSPEC_PORT		(-1)
+
+/*
  * In-kernel mount arguments
  */
 struct nfs_parsed_mount_data {
@@ -63,6 +68,7 @@ struct nfs_parsed_mount_data {
 	unsigned int		auth_flavor_len;
 	rpc_authflavor_t	auth_flavors[1];
 	char			*client_address;
+	unsigned int		version;
 	unsigned int		minorversion;
 	char			*fscache_uniq;
 
@@ -71,7 +77,7 @@ struct nfs_parsed_mount_data {
 		size_t			addrlen;
 		char			*hostname;
 		u32			version;
-		unsigned short		port;
+		int			port;
 		unsigned short		protocol;
 	} mount_server;
 
@@ -80,7 +86,7 @@ struct nfs_parsed_mount_data {
 		size_t			addrlen;
 		char			*hostname;
 		char			*export_path;
-		unsigned short		port;
+		int			port;
 		unsigned short		protocol;
 	} nfs_server;
 
diff -up linux-2.6.30.i686/fs/nfs/super.c.save linux-2.6.30.i686/fs/nfs/super.c
--- linux-2.6.30.i686/fs/nfs/super.c.save	2009-09-10 10:14:24.000000000 -0400
+++ linux-2.6.30.i686/fs/nfs/super.c	2009-09-10 15:14:10.000000000 -0400
@@ -73,7 +73,7 @@ enum {
 	Opt_cto, Opt_nocto,
 	Opt_ac, Opt_noac,
 	Opt_lock, Opt_nolock,
-	Opt_v2, Opt_v3,
+	Opt_v2, Opt_v3, Opt_v4,
 	Opt_udp, Opt_tcp, Opt_rdma,
 	Opt_acl, Opt_noacl,
 	Opt_rdirplus, Opt_nordirplus,
@@ -127,6 +127,7 @@ static const match_table_t nfs_mount_opt
 	{ Opt_nolock, "nolock" },
 	{ Opt_v2, "v2" },
 	{ Opt_v3, "v3" },
+	{ Opt_v4, "v4" },
 	{ Opt_udp, "udp" },
 	{ Opt_tcp, "tcp" },
 	{ Opt_rdma, "rdma" },
@@ -272,6 +273,10 @@ static const struct super_operations nfs
 };
 
 #ifdef CONFIG_NFS_V4
+static int nfs4_validate_text_mount_data(void *options,
+	struct nfs_parsed_mount_data *args, const char *dev_name);
+static int nfs4_try_mount(int flags, const char *dev_name,
+	struct nfs_parsed_mount_data *data, struct vfsmount *mnt);
 static int nfs4_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 static int nfs4_remote_get_sb(struct file_system_type *fs_type,
@@ -866,6 +871,21 @@ void nfs_parse_ip_address(char *string, 
 }
 
 /*
+ * Select between a default port value and a user-specified port value.
+ * If a zero value is set, then autobind will be used.
+ */
+static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port,
+				 const unsigned short default_port)
+{
+	unsigned short port = default_port;
+
+	if (parsed_port != NFS_UNSPEC_PORT)
+		port = parsed_port;
+
+	nfs_set_port(sap, port);
+}
+
+/*
  * Sanity check the NFS transport protocol.
  *
  */
@@ -1047,10 +1067,18 @@ static int nfs_parse_mount_options(char 
 			break;
 		case Opt_v2:
 			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 2;
 			break;
 		case Opt_v3:
 			mnt->flags |= NFS_MOUNT_VER3;
+			mnt->version = 3;
 			break;
+#ifdef CONFIG_NFS_V4
+		case Opt_v4:
+			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 4;
+			break;
+#endif
 		case Opt_udp:
 			mnt->flags &= ~NFS_MOUNT_TCP;
 			mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1264,10 +1292,18 @@ static int nfs_parse_mount_options(char 
 			switch (option) {
 			case NFS2_VERSION:
 				mnt->flags &= ~NFS_MOUNT_VER3;
+				mnt->version = 2;
 				break;
 			case NFS3_VERSION:
 				mnt->flags |= NFS_MOUNT_VER3;
+				mnt->version = 3;
+				break;
+#ifdef CONFIG_NFS_V4
+			case NFS4_VERSION:
+				mnt->flags &= ~NFS_MOUNT_VER3;
+				mnt->version = 4;
 				break;
+#endif
 			default:
 				goto out_invalid_value;
 			}
@@ -1485,11 +1521,7 @@ static int nfs_try_mount(struct nfs_pars
 		args->mount_server.addrlen = args->nfs_server.addrlen;
 	}
 	request.salen = args->mount_server.addrlen;
-
-	/*
-	 * autobind will be used if mount_server.port == 0
-	 */
-	nfs_set_port(request.sap, args->mount_server.port);
+	nfs_set_default_port(request.sap, args->mount_server.port, 0);
 
 	/*
 	 * Now ask the mount server to map our export path
@@ -1661,6 +1693,7 @@ static int nfs_validate_mount_data(void 
 				   const char *dev_name)
 {
 	struct nfs_mount_data *data = (struct nfs_mount_data *)options;
+	struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
 
 	if (data == NULL)
 		goto out_no_data;
@@ -1672,10 +1705,11 @@ static int nfs_validate_mount_data(void 
 	args->acregmax		= NFS_DEF_ACREGMAX;
 	args->acdirmin		= NFS_DEF_ACDIRMIN;
 	args->acdirmax		= NFS_DEF_ACDIRMAX;
-	args->mount_server.port	= 0;	/* autobind unless user sets port */
-	args->nfs_server.port	= 0;	/* autobind unless user sets port */
+	args->mount_server.port	= NFS_UNSPEC_PORT;
+	args->nfs_server.port	= NFS_UNSPEC_PORT;
 	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
 	args->auth_flavors[0]	= RPC_AUTH_UNIX;
+	args->minorversion	= 0;
 
 	switch (data->version) {
 	case 1:
@@ -1697,8 +1731,11 @@ static int nfs_validate_mount_data(void 
 			if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
 				goto out_invalid_fh;
 			mntfh->size = data->root.size;
-		} else
+			args->version = 3;
+		} else {
 			mntfh->size = NFS2_FHSIZE;
+			args->version = 2;
+		}
 
 
 		memcpy(mntfh->data, data->root.data, mntfh->size);
@@ -1720,11 +1757,9 @@ static int nfs_validate_mount_data(void 
 		args->acdirmin		= data->acdirmin;
 		args->acdirmax		= data->acdirmax;
 
-		memcpy(&args->nfs_server.address, &data->addr,
-		       sizeof(data->addr));
+		memcpy(sap, &data->addr, sizeof(data->addr));
 		args->nfs_server.addrlen = sizeof(data->addr);
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(sap))
 			goto out_no_address;
 
 		if (!(data->flags & NFS_MOUNT_TCP))
@@ -1772,12 +1807,18 @@ static int nfs_validate_mount_data(void 
 		if (nfs_parse_mount_options((char *)options, args) == 0)
 			return -EINVAL;
 
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(sap))
 			goto out_no_address;
 
-		nfs_set_port((struct sockaddr *)&args->nfs_server.address,
-				args->nfs_server.port);
+		if (args->version == 4)
+#ifdef CONFIG_NFS_V4
+			return nfs4_validate_text_mount_data(options,
+							     args, dev_name);
+#else
+			goto out_v4_not_compiled;
+#endif
+
+		nfs_set_default_port(sap, args->nfs_server.port, 0);
 
 		nfs_set_mount_transport_protocol(args);
 
@@ -1825,6 +1866,12 @@ out_v3_not_compiled:
 	return -EPROTONOSUPPORT;
 #endif /* !CONFIG_NFS_V3 */
 
+#ifndef CONFIG_NFS_V4
+out_v4_not_compiled:
+	dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
+	return -EPROTONOSUPPORT;
+#endif /* !CONFIG_NFS_V4 */
+
 out_nomem:
 	dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
 	return -ENOMEM;
@@ -2120,6 +2167,14 @@ static int nfs_get_sb(struct file_system
 	if (error < 0)
 		goto out;
 
+#ifdef CONFIG_NFS_V4
+	if (data->version == 4) {
+		error = nfs4_try_mount(flags, dev_name, data, mnt);
+		kfree(data->client_address);
+		goto out;
+	}
+#endif	/* CONFIG_NFS_V4 */
+
 	/* Get a volume representation */
 	server = nfs_create_server(data, mntfh);
 	if (IS_ERR(server)) {
@@ -2317,6 +2372,43 @@ static void nfs4_validate_mount_flags(st
 	args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
 }
 
+static int nfs4_validate_text_mount_data(void *options,
+					 struct nfs_parsed_mount_data *args,
+					 const char *dev_name)
+{
+	struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
+
+	nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT);
+
+	nfs_validate_transport_protocol(args);
+
+	nfs4_validate_mount_flags(args);
+
+	if (args->version != 4) {
+		dfprintk(MOUNT,
+			 "NFS4: Illegal mount version\n");
+		return -EINVAL;
+	}
+
+	if (args->auth_flavor_len > 1) {
+		dfprintk(MOUNT,
+			 "NFS4: Too many RPC auth flavours specified\n");
+		return -EINVAL;
+	}
+
+	if (args->client_address == NULL) {
+		dfprintk(MOUNT,
+			 "NFS4: mount program didn't pass callback address\n");
+		return -EINVAL;
+	}
+
+	return nfs_parse_devname(dev_name,
+				   &args->nfs_server.hostname,
+				   NFS4_MAXNAMLEN,
+				   &args->nfs_server.export_path,
+				   NFS4_MAXPATHLEN);
+}
+
 /*
  * Validate NFSv4 mount options
  */
@@ -2324,7 +2416,7 @@ static int nfs4_validate_mount_data(void
 				    struct nfs_parsed_mount_data *args,
 				    const char *dev_name)
 {
-	struct sockaddr_in *ap;
+	struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
 	struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
 	char *c;
 
@@ -2337,23 +2429,22 @@ static int nfs4_validate_mount_data(void
 	args->acregmax		= NFS_DEF_ACREGMAX;
 	args->acdirmin		= NFS_DEF_ACDIRMIN;
 	args->acdirmax		= NFS_DEF_ACDIRMAX;
-	args->nfs_server.port	= NFS_PORT; /* 2049 unless user set port= */
+	args->nfs_server.port	= NFS_UNSPEC_PORT;
 	args->auth_flavors[0]	= RPC_AUTH_UNIX;
 	args->auth_flavor_len	= 0;
+	args->version		= 4;
 	args->minorversion	= 0;
 
 	switch (data->version) {
 	case 1:
-		ap = (struct sockaddr_in *)&args->nfs_server.address;
 		if (data->host_addrlen > sizeof(args->nfs_server.address))
 			goto out_no_address;
 		if (data->host_addrlen == 0)
 			goto out_no_address;
 		args->nfs_server.addrlen = data->host_addrlen;
-		if (copy_from_user(ap, data->host_addr, data->host_addrlen))
+		if (copy_from_user(sap, data->host_addr, data->host_addrlen))
 			return -EFAULT;
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (nfs_verify_server_address(sap))
 			goto out_no_address;
 
 		if (data->auth_flavourlen) {
@@ -2399,39 +2490,14 @@ static int nfs4_validate_mount_data(void
 		nfs_validate_transport_protocol(args);
 
 		break;
-	default: {
-		int status;
-
+	default:
 		if (nfs_parse_mount_options((char *)options, args) == 0)
 			return -EINVAL;
 
-		if (!nfs_verify_server_address((struct sockaddr *)
-						&args->nfs_server.address))
+		if (!nfs_verify_server_address(sap))
 			return -EINVAL;
 
-		nfs_set_port((struct sockaddr *)&args->nfs_server.address,
-				args->nfs_server.port);
-
-		nfs_validate_transport_protocol(args);
-
-		nfs4_validate_mount_flags(args);
-
-		if (args->auth_flavor_len > 1)
-			goto out_inval_auth;
-
-		if (args->client_address == NULL)
-			goto out_no_client_address;
-
-		status = nfs_parse_devname(dev_name,
-					   &args->nfs_server.hostname,
-					   NFS4_MAXNAMLEN,
-					   &args->nfs_server.export_path,
-					   NFS4_MAXPATHLEN);
-		if (status < 0)
-			return status;
-
-		break;
-		}
+		return nfs4_validate_text_mount_data(options, args, dev_name);
 	}
 
 	return 0;
@@ -2448,10 +2514,6 @@ out_inval_auth:
 out_no_address:
 	dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
 	return -EINVAL;
-
-out_no_client_address:
-	dfprintk(MOUNT, "NFS4: mount program didn't pass callback address\n");
-	return -EINVAL;
 }
 
 /*
@@ -2618,6 +2680,34 @@ out_err:
 	return ret;
 }
 
+static int nfs4_try_mount(int flags, const char *dev_name,
+			 struct nfs_parsed_mount_data *data,
+			 struct vfsmount *mnt)
+{
+	char *export_path;
+	struct vfsmount *root_mnt;
+	int error;
+
+	dfprintk(MOUNT, "--> nfs4_try_mount()\n");
+
+	export_path = data->nfs_server.export_path;
+	data->nfs_server.export_path = "/";
+	root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
+			data->nfs_server.hostname);
+	data->nfs_server.export_path = export_path;
+
+	error = PTR_ERR(root_mnt);
+	if (IS_ERR(root_mnt))
+		goto out;
+
+	error = nfs_follow_remote_path(root_mnt, export_path, mnt);
+
+out:
+	dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", error,
+			error != 0 ? " [error]" : "");
+	return error;
+}
+
 /*
  * Get the superblock for an NFS4 mountpoint
  */
@@ -2625,8 +2715,6 @@ static int nfs4_get_sb(struct file_syste
 	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
 	struct nfs_parsed_mount_data *data;
-	char *export_path;
-	struct vfsmount *root_mnt;
 	int error = -ENOMEM;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -2638,17 +2726,7 @@ static int nfs4_get_sb(struct file_syste
 	if (error < 0)
 		goto out;
 
-	export_path = data->nfs_server.export_path;
-	data->nfs_server.export_path = "/";
-	root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
-			data->nfs_server.hostname);
-	data->nfs_server.export_path = export_path;
-
-	error = PTR_ERR(root_mnt);
-	if (IS_ERR(root_mnt))
-		goto out;
-
-	error = nfs_follow_remote_path(root_mnt, export_path, mnt);
+	error = nfs4_try_mount(flags, dev_name, data, mnt);
 
 out:
 	kfree(data->client_address);
diff -up linux-2.6.30.i686/include/linux/nfs4.h.save linux-2.6.30.i686/include/linux/nfs4.h
--- linux-2.6.30.i686/include/linux/nfs4.h.save	2009-09-10 10:14:38.000000000 -0400
+++ linux-2.6.30.i686/include/linux/nfs4.h	2009-09-10 11:06:38.000000000 -0400
@@ -472,6 +472,7 @@ enum lock_type4 {
 
 #define NFSPROC4_NULL 0
 #define NFSPROC4_COMPOUND 1
+#define NFS4_VERSION 4
 #define NFS4_MINOR_VERSION 0
 
 #if defined(CONFIG_NFS_V4_1)

linux-2.6-rfkill-all.patch:
 include/linux/input.h  |    2 ++
 include/linux/rfkill.h |    2 +-
 net/rfkill/input.c     |    8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-rfkill-all.patch ---
diff --git a/include/linux/input.h b/include/linux/input.h
index 8b3bc3e..20a622e 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -595,6 +595,8 @@ struct input_absinfo {
 #define KEY_NUMERIC_STAR	0x20a
 #define KEY_NUMERIC_POUND	0x20b
 
+#define KEY_RFKILL		0x20c /* Key that controls all radios */
+
 /* We avoid low common keys in module aliases so they don't get huge. */
 #define KEY_MIN_INTERESTING	KEY_MUTE
 #define KEY_MAX			0x2ff
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 278777f..4c39f7e 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -32,7 +32,7 @@
 /**
  * enum rfkill_type - type of rfkill switch.
  *
- * @RFKILL_TYPE_ALL: toggles all switches (userspace only)
+ * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
  * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
  * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
  * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
index a7295ad..3713d7e 100644
--- a/net/rfkill/input.c
+++ b/net/rfkill/input.c
@@ -212,6 +212,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
 		case KEY_WIMAX:
 			rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
 			break;
+		case KEY_RFKILL:
+			rfkill_schedule_toggle(RFKILL_TYPE_ALL);
+			break;
 		}
 	} else if (type == EV_SW && code == SW_RFKILL_ALL)
 		rfkill_schedule_evsw_rfkillall(data);
@@ -295,6 +298,11 @@ static const struct input_device_id rfkill_ids[] = {
 		.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
 	},
 	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(KEY_RFKILL)] = BIT_MASK(KEY_RFKILL) },
+	},
+	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
 		.evbit = { BIT(EV_SW) },
 		.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },

linux-2.6-rtc-show-hctosys.patch:
 Documentation/rtc.txt     |    2 ++
 b/Documentation/rtc.txt   |   22 ++++++++++++++++++++++
 b/drivers/rtc/rtc-sysfs.c |   14 ++++++++++++++
 3 files changed, 38 insertions(+)

--- NEW FILE linux-2.6-rtc-show-hctosys.patch ---
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 8deffcd..216bb8c 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -135,6 +135,28 @@ a high functionality RTC is integrated into the SOC.  That system might read
 the system clock from the discrete RTC, but use the integrated one for all
 other tasks, because of its greater functionality.
 
+SYSFS INTERFACE
+---------------
+
+The sysfs interface under /sys/class/rtc/rtcN provides access to various
+rtc attributes without requiring the use of ioctls. All dates and times
+are in the RTC's timezone, rather than in system time.
+
+date:  	   	 RTC-provided date
+max_user_freq:	 The maximum interrupt rate an unprivileged user may request
+		 from this RTC.
+name:		 The name of the RTC corresponding to this sysfs directory
+since_epoch:	 The number of seconds since the epoch according to the RTC
+time:		 RTC-provided time
+wakealarm:	 The time at which the clock will generate a system wakeup
+		 event. This is a one shot wakeup event, so must be reset
+		 after wake if a daily wakeup is required. Format is either
+		 seconds since the epoch or, if there's a leading +, seconds
+		 in the future.
+
+IOCTL INTERFACE
+---------------
+
 The ioctl() calls supported by /dev/rtc are also supported by the RTC class
 framework.  However, because the chips and systems are not standardized,
 some PC/AT functionality might not be provided.  And in the same way, some

diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 216bb8c..baac51f 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -143,6 +143,8 @@ rtc attributes without requiring the use of ioctls. All dates and times
 are in the RTC's timezone, rather than in system time.
 
 date:  	   	 RTC-provided date
+hctosys:   	 1 if the RTC provided the system time at boot via the
+		 CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
 max_user_freq:	 The maximum interrupt rate an unprivileged user may request
 		 from this RTC.
 name:		 The name of the RTC corresponding to this sysfs directory
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 2531ce4..7dd23a6 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -102,6 +102,19 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
 	return n;
 }
 
+static ssize_t
+rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+#ifdef CONFIG_RTC_HCTOSYS_DEVICE
+	if (strcmp(dev_name(&to_rtc_device(dev)->dev),
+		   CONFIG_RTC_HCTOSYS_DEVICE) == 0)
+		return sprintf(buf, "1\n");
+	else
+#endif
+		return sprintf(buf, "0\n");
+}
+
 static struct device_attribute rtc_attrs[] = {
 	__ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
 	__ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
@@ -109,6 +122,7 @@ static struct device_attribute rtc_attrs[] = {
 	__ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
 	__ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,
 			rtc_sysfs_set_max_user_freq),
+	__ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL),
 	{ },
 };
 


linux-2.6-scsi-sd-fix-oops-during-scanning.patch:
 sd.c |    2 ++
 1 file changed, 2 insertions(+)

--- NEW FILE linux-2.6-scsi-sd-fix-oops-during-scanning.patch ---
From: James Bottomley <James.Bottomley at suse.de>
Date: Fri, 21 Aug 2009 15:47:54 +0000 (-0600)
Subject: [SCSI] fix oops during scsi scanning
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjejb%2Fscsi-misc-2.6.git;a=commitdiff_plain;h=ea038f63ac52439e7816295fa6064fe95e6c1f51

[SCSI] fix oops during scsi scanning

Chris Webb reported:
  p0# uname -a
  Linux f7ea8425-d45b-490f-a738-d181d0df6963.host.elastichosts.com 2.6.30.4-elastic-lon-p #2 SMP PREEMPT Thu Aug 20 14:30:50 BST 2009 x86_64 Intel(R) Xeon(R) CPU E5420 @ 2.50GHz GenuineIntel GNU/Linux
  p0# zgrep SCAN_ASYNC /proc/config.gz
  # CONFIG_SCSI_SCAN_ASYNC is not set

  p0# cat /var/log/kern/2009-08-20
  [...]
  15:27:10.485 kernel: scsi9 : iSCSI Initiator over TCP/IP
  15:27:11.493 kernel: scsi 9:0:0:0: RAID              IET      Controller       0001 PQ: 0 ANSI: 5
  15:27:11.493 kernel: scsi 9:0:0:0: Attached scsi generic sg6 type 12
  15:27:11.495 kernel: scsi 9:0:0:1: Direct-Access     IET      VIRTUAL-DISK     0001 PQ: 0 ANSI: 5
  15:27:11.495 kernel: sd 9:0:0:1: Attached scsi generic sg7 type 0
  15:27:11.495 kernel: sd 9:0:0:1: [sdg] 4194304 512-byte hardware sectors: (2.14 GB/2.00 GiB)
  15:27:11.495 kernel: sd 9:0:0:1: [sdg] Write Protect is off
  15:27:11.495 kernel: sd 9:0:0:1: [sdg] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
  15:27:13.012 kernel: sdg:<6>scsi 9:0:0:1: [sdg] Unhandled error code
  15:27:13.012 kernel: scsi 9:0:0:1: [sdg] Result: hostbyte=0x07 driverbyte=0x00
  15:27:13.012 kernel: end_request: I/O error, dev sdg, sector 0
  15:27:13.012 kernel: Buffer I/O error on device sdg, logical block 0
  15:27:13.012 kernel: ldm_validate_partition_table(): Disk read failed.
  15:27:13.012 kernel: unable to read partition table
  15:27:13.014 kernel: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
  15:27:13.014 kernel: IP: [<ffffffff803f0d77>] disk_part_iter_next+0x74/0xfd
  15:27:13.014 kernel: PGD 82ad0b067 PUD 82cd7e067 PMD 0
  15:27:13.014 kernel: Oops: 0000 [#1] PREEMPT SMP
  15:27:13.014 kernel: last sysfs file: /sys/devices/platform/host9/session4/iscsi_session/session4/ifacename
  15:27:13.014 kernel: CPU 5
  15:27:13.014 kernel: Modules linked in:
  15:27:13.014 kernel: Pid: 13999, comm: async/0 Not tainted 2.6.30.4-elastic-lon-p #2 X7DBN
  15:27:13.014 kernel: RIP: 0010:[<ffffffff803f0d77>]  [<ffffffff803f0d77>] disk_part_iter_next+0x74/0xfd
  15:27:13.014 kernel: RSP: 0018:ffff88066afa3dd0  EFLAGS: 00010246
  15:27:13.014 kernel: RAX: ffff88082b58a000 RBX: ffff88066afa3e00 RCX: 0000000000000000
  15:27:13.014 kernel: RDX: 0000000000000000 RSI: ffff88082b58a000 RDI: 0000000000000000
  15:27:13.014 kernel: RBP: ffff88066afa3df0 R08: ffff88066afa2000 R09: ffff8806a204f000
  15:27:13.014 kernel: R10: 000000fb12c7d274 R11: ffff8806c2bf0628 R12: ffff88066afa3e00
  15:27:13.014 kernel: R13: ffff88082c829a00 R14: 0000000000000000 R15: ffff8806bc50c920
  15:27:13.014 kernel: FS:  0000000000000000(0000) GS:ffff88002818a000(0000) knlGS:0000000000000000
  15:27:13.014 kernel: CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
  15:27:13.014 kernel: CR2: 0000000000000010 CR3: 000000082ade3000 CR4: 00000000000426e0
  15:27:13.014 kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  15:27:13.014 kernel: DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
  15:27:13.014 kernel: Process async/0 (pid: 13999, threadinfo ffff88066afa2000, task ffff8806c2bf05e0)
  15:27:13.014 kernel: Stack:
  15:27:13.014 kernel: 0000000000000000 ffff88066afa3e00 ffff88066afa3e00 ffff88082c829a00
  15:27:13.014 kernel: ffff88066afa3e40 ffffffff80306feb ffff88082b58a000 0000000000000000
  15:27:13.014 kernel: 0000000000000001 ffff8806bc50c920 ffff88066afa3e40 ffff88082b58a000
  15:27:13.014 kernel: Call Trace:
  15:27:13.014 kernel: [<ffffffff80306feb>] register_disk+0x122/0x13a
  15:27:13.014 kernel: [<ffffffff803f0b0f>] add_disk+0xaa/0x106
  15:27:13.014 kernel: [<ffffffff80493609>] sd_probe_async+0x198/0x25b
  15:27:13.014 kernel: [<ffffffff80270482>] async_thread+0x10c/0x20d
  15:27:13.014 kernel: [<ffffffff802545ff>] ? default_wake_function+0x0/0xf
  15:27:13.014 kernel: [<ffffffff80270376>] ? async_thread+0x0/0x20d
  15:27:13.014 kernel: [<ffffffff8026ad89>] kthread+0x55/0x80
  15:27:13.014 kernel: [<ffffffff8022be6a>] child_rip+0xa/0x20
  15:27:13.014 kernel: [<ffffffff8026ad34>] ? kthread+0x0/0x80
  15:27:13.014 kernel: [<ffffffff8022be60>] ? child_rip+0x0/0x20
  15:27:13.014 kernel: Code: c8 ff 80 e1 0c b9 00 00 00 00 0f 44 c1 41 83 cd ff 48 8d 7a 20 48 be ff ff ff ff 08 00 00 00 48 b9 00 00 00 00 08 00 00 00 eb 50 <8b> 42 10 41 bd 01 00 00 00 eb db 4c 63 c2 4e 8d 04 c7 4d 8b 20
  15:27:13.015 kernel: RIP  [<ffffffff803f0d77>] disk_part_iter_next+0x74/0xfd
  15:27:13.015 kernel: RSP <ffff88066afa3dd0>
  15:27:13.015 kernel: CR2: 0000000000000010
  15:27:13.015 kernel: ---[ end trace 6104b56ef5590e25 ]---

The problem is caused because the async scanning split in sd.c doesn't hold
any reference to the device when it kicks off the async piece.  What's
happening is that an iSCSI disconnect is destorying the device again *before*
the async sd scanning thread even starts.  Fix this by taking a reference
before starting the thread and dropping it again when the thread completes.

Reported-by: Chris Webb <chris at arachsys.com>
Cc: Stable Tree <stable at kernel.org>
Signed-off-by: James Bottomley <James.Bottomley at suse.de>
---

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b7b9fec..a89c421 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2021,6 +2021,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
 		  sdp->removable ? "removable " : "");
+	put_device(&sdkp->dev);
 }
 
 /**
@@ -2106,6 +2107,7 @@ static int sd_probe(struct device *dev)
 
 	get_device(&sdp->sdev_gendev);
 
+	get_device(&sdkp->dev);	/* prevent release before async_schedule */
 	async_schedule(sd_probe_async, sdkp);
 
 	return 0;

linux-2.6-scsi-sg-fix-oops-in-error-path.patch:
 sg.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-scsi-sg-fix-oops-in-error-path.patch ---
From: Michal Schmidt <mschmidt at redhat.com>
Date: Thu, 3 Sep 2009 12:27:08 +0000 (+0200)
Subject: [SCSI] sg: fix oops in the error path in sg_build_indirect()
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjejb%2Fscsi-misc-2.6.git;a=commitdiff_plain;h=e71044ee2efa4792e21d243b03d49006db66aec9

[SCSI] sg: fix oops in the error path in sg_build_indirect()

When the allocation fails in sg_build_indirect(), an oops happens in
the error path. It's caused by an obvious typo.

Signed-off-by: Michal Schmidt <mschmidt at redhat.com>
Reported-by: Bob Tracy <rct at gherkin.frus.com>
Acked-by: Douglas Gilbert <dgilbert at interlog.com>
Cc: Stable Tree <stable at kernel.org>
Signed-off-by: James Bottomley <James.Bottomley at suse.de>
---

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9230402..4968c4c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1811,7 +1811,7 @@ retry:
 	return 0;
 out:
 	for (i = 0; i < k; i++)
-		__free_pages(schp->pages[k], order);
+		__free_pages(schp->pages[i], order);
 
 	if (--order >= 0)
 		goto retry;

linux-2.6.31-modules-ro-nx.patch:
 include/linux/module.h |    3 +
 kernel/module.c        |  126 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 126 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.31-modules-ro-nx.patch ---
>From davej  Fri Sep 11 11:06:50 2009
Return-Path: linux-kernel-owner at vger.kernel.org
X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-5.5 required=5.0 tests=AWL,BAYES_00,
	RCVD_IN_DNSWL_MED,SARE_MSGID_LONG40,UNPARSEABLE_RELAY autolearn=ham
	version=3.2.5
Received: from mail.corp.redhat.com [10.5.5.51]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.9)
	for <davej at localhost> (single-drop); Fri, 11 Sep 2009 11:06:50 -0400 (EDT)
Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO
 zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by
 mail04.corp.redhat.com with LMTP; Thu, 10 Sep 2009 22:51:21 -0400 (EDT)
Received: from localhost (localhost.localdomain [127.0.0.1])
	by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id E57644F1AB;
	Thu, 10 Sep 2009 22:51:20 -0400 (EDT)
Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1])
	by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id PqMpQop0Dbp5; Thu, 10 Sep 2009 22:51:20 -0400 (EDT)
Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16])
	by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A56F64F1AA;
	Thu, 10 Sep 2009 22:51:20 -0400 (EDT)
Received: from mx1.redhat.com (ext-mx08.extmail.prod.ext.phx2.redhat.com [10.5.110.12])
	by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n8B2pDoM001214;
	Thu, 10 Sep 2009 22:51:13 -0400
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
	by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n8B2jC2e031184;
	Thu, 10 Sep 2009 22:51:01 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1753321AbZIKCur (ORCPT <rfc822;mrezanin at redhat.com> + 41 others);
	Thu, 10 Sep 2009 22:50:47 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1752432AbZIKCuq
	(ORCPT <rfc822;linux-kernel-outgoing>);
	Thu, 10 Sep 2009 22:50:46 -0400
Received: from mail-yw0-f174.google.com ([209.85.211.174]:34234 "EHLO
	mail-yw0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
	with ESMTP id S1752401AbZIKCup (ORCPT
	<rfc822;linux-kernel at vger.kernel.org>);
	Thu, 10 Sep 2009 22:50:45 -0400
Received: by ywh4 with SMTP id 4so897627ywh.5
        for <multiple recipients>; Thu, 10 Sep 2009 19:50:47 -0700 (PDT)
DKIM-Signature: 	v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=domainkey-signature:mime-version:received:date:message-id:subject
         :from:to:cc:content-type;
        bh=p3+H2ZvljQZotPAF9Gb+FxecqVT3MH9YeBjUUKwwvY0=;
        b=JTV6NmVCgyrG6SVi/FbmJR4FeIQuc44rC3EV0D1A8qPb+xMwNYK5QlD8do+3+FKgbc
         CH/kgCjakj8e5v4ipROLQjPEiN/TETq15ITPKToCOHKve4jS1GMgkZYyYScpBfOj7N9R
         VaWi9sbsNBvUtf1wS83Uqy4GBjZ88MEoBetrs=
DomainKey-Signature: a=rsa-sha1; c=nofws;
        d=gmail.com; s=gamma;
        h=mime-version:date:message-id:subject:from:to:cc:content-type;
        b=Ksz1JD3HRA+cyDH560RvcyHLpdr4+4Tost2JUGQV5a1m/XC/zwqLdXWNlkWTsuNVvJ
         n+vlXd8VrHE+9h54vf+BMqmK+3LB6Q1iV3nLFpRoU7qaEdnPrWdRcCi8Ot6vIzLrHLf2
         Xu6y7fJWaLQ+cbIGNY2LGR5UlkBul7kaj1API=
MIME-Version: 1.0
Received: by 10.150.17.5 with SMTP id 5mr3930758ybq.195.1252637447825; Thu, 10 
	Sep 2009 19:50:47 -0700 (PDT)
Date: 	Thu, 10 Sep 2009 22:50:47 -0400
Message-ID: <817ecb6f0909101950v2fc6dc6u5cbc40cd9a9dde77 at mail.gmail.com>
Subject: [PATCH v6] RO/NX protection for loadable kernel modules
From: Siarhei Liakh <sliakh.lkml at gmail.com>
To: linux-kernel at vger.kernel.org, linux-security-module at vger.kernel.org,
        linux-next at vger.kernel.org
Cc: Arjan van de Ven <arjan at infradead.org>, James Morris <jmorris at namei.org>,
        Andrew Morton <akpm at linux-foundation.org>, Andi Kleen <ak at muc.de>,
        Thomas Gleixner <tglx at linutronix.de>, "H. Peter Anvin" <hpa at zytor.com>,
        Ingo Molnar <mingo at elte.hu>, Rusty Russell <rusty at rustcorp.com.au>,
        Stephen Rothwell <sfr at canb.auug.org.au>
Content-Type: text/plain; charset=ISO-8859-1
Sender: linux-kernel-owner at vger.kernel.org
Precedence: bulk
List-ID: <linux-kernel.vger.kernel.org>
X-Mailing-List: 	linux-kernel at vger.kernel.org
X-RedHat-Spam-Score: -4  (RCVD_IN_DNSWL_MED)
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16
X-Scanned-By: MIMEDefang 2.67 on 10.5.110.12
Status: RO
Content-Length: 8042
Lines: 260

This patch is a logical extension of the protection provided by
CONFIG_DEBUG_RODATA to LKMs. The protection is provided by splitting
module_core and module_init into three logical parts each and setting
appropriate page access permissions for each individual section:

 1. Code: RO+X
 2. RO data: RO+NX
 3. RW data: RW+NX

In order to achieve proper protection, layout_sections() have been
modified to align each of the three parts mentioned above onto page
boundary. Next, the corresponding page access permissions are set
right before successful exit from load_module(). Further, free_module()
and sys_init_module have been modified to set module_core and
module_init as RW+NX right before calling module_free().

By default, the original section layout is preserved and RO/NX is
enforced only for whole pages of same content.
However, when compiled with CONFIG_DEBUG_RODATA=y, the patch
will page-align each group of sections to ensure that each page contains
only one type of content.
RO/NX enforcement is active on x86 only.

v1: Initial proof-of-concept patch.

v2: The patch have been re-written to reduce the number of #ifdefs and
to make it architecture-agnostic. Code formatting have been corrected also.

v3: Opportunistic RO/NX protectiuon is now unconditional. Section
page-alignment is enabled when CONFIG_DEBUG_RODATA=y.

v4: Removed most macros and improved coding style.

v5: Changed page-alignment and RO/NX section size calculation

v6: Fixed comments. Restricted RO/NX enforcement to x86 only

The patch have been developed for Linux 2.6.30 by Siarhei Liakh
<sliakh.lkml at gmail.com> and Xuxian Jiang <jiang at cs.ncsu.edu>.

---

Signed-off-by: Siarhei Liakh <sliakh.lkml at gmail.com>
Signed-off-by: Xuxian Jiang <jiang at cs.ncsu.edu>
Acked-by: Arjan van de Ven <arjan at linux.intel.com>

diff --git a/include/linux/module.h b/include/linux/module.h
index 627ac08..5ba770e 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -293,6 +293,9 @@ struct module
 	/* The size of the executable code in each section.  */
 	unsigned int init_text_size, core_text_size;

+	/* Size of RO sections of the module (text+rodata) */
+	unsigned int init_ro_size, core_ro_size;
+
 	/* Arch-specific module values */
 	struct mod_arch_specific arch;

diff --git a/kernel/module.c b/kernel/module.c
index e797812..660278a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -54,6 +54,7 @@
 #include <linux/async.h>
 #include <linux/percpu.h>
 #include <linux/kmemleak.h>
+#include <linux/pfn.h>
 
 #if 0
 #define DEBUGP printk
@@ -63,6 +64,26 @@
 #define ARCH_SHF_SMALL 0
 #endif

+/*
+ * Modules' sections will be aligned on page boundaries
+ * to ensure complete separation of code and data, but
+ * only when CONFIG_DEBUG_RODATA=y
+ */
+#ifdef CONFIG_DEBUG_RODATA
+#define debug_align(X) ALIGN(X, PAGE_SIZE)
+#else
+#define debug_align(X) (X)
+#endif
+
+/*
+ * Given BASE and SIZE this macro calculates the number of pages the
+ * memory regions occupies
+ */
+#define NUMBER_OF_PAGES(BASE, SIZE) ((SIZE > 0) ?		\
+		(PFN_DOWN((unsigned long)BASE + SIZE - 1) -	\
+			 PFN_DOWN((unsigned long)BASE) + 1)	\
+		: (0UL))
+
 /* If this is set, the section belongs in the init part of the module */
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

@@ -1471,6 +1492,69 @@ static int __unlink_module(void *_mod)
 	return 0;
 }

+/*
+ * LKM RO/NX protection: protect module's text/ro-data
+ * from modification and any data from execution.
+ */
+static void set_section_ro_nx(void *base,
+			unsigned long text_size,
+			unsigned long ro_size,
+			unsigned long total_size)
+{
+#ifdef CONFIG_X86
+	/* begin and end PFNs of the current subsection */
+	unsigned long begin_pfn;
+	unsigned long end_pfn;
+
+	/*
+	 * Set RO for module text and RO-data:
+	 * - Always protect first page.
+	 * - Do not protect last partial page.
+	 */
+	if (ro_size > 0) {
+		begin_pfn = PFN_DOWN((unsigned long)base);
+		end_pfn = PFN_DOWN((unsigned long)base + ro_size);
+		if (end_pfn > begin_pfn)
+			set_memory_ro(begin_pfn << PAGE_SHIFT,
+						end_pfn - begin_pfn);
+	}
+
+	/*
+	 * Set NX permissions for module data:
+	 * - Do not protect first partial page.
+	 * - Always protect last page.
+	 */
+	if (total_size > text_size) {
+		begin_pfn = PFN_UP((unsigned long)base + text_size);
+		end_pfn = PFN_UP((unsigned long)base + total_size);
+		if (end_pfn > begin_pfn)
+			set_memory_nx(begin_pfn << PAGE_SHIFT,
+						end_pfn - begin_pfn);
+	}
+#endif
+}
+
+/* Setting memory back to RW+NX before releasing it */
+void unset_section_ro_nx(struct module *mod, void *module_region)
+{
+#ifdef CONFIG_X86
+	unsigned long total_pages;
+
+	if (mod->module_core == module_region) {
+		/* Set core as NX+RW */
+		total_pages = NUMBER_OF_PAGES(mod->module_core, mod->core_size);
+		set_memory_nx((unsigned long)mod->module_core, total_pages);
+		set_memory_rw((unsigned long)mod->module_core, total_pages);
+
+	} else if (mod->module_init == module_region) {
+		/* Set init as NX+RW */
+		total_pages = NUMBER_OF_PAGES(mod->module_init, mod->init_size);
+		set_memory_nx((unsigned long)mod->module_init, total_pages);
+		set_memory_rw((unsigned long)mod->module_init, total_pages);
+	}
+#endif
+}
+
 /* Free a module, remove from lists, etc (must hold module_mutex). */
 static void free_module(struct module *mod)
 {
@@ -1493,6 +1577,7 @@ static void free_module(struct module *mod)
 	ftrace_release(mod->module_core, mod->core_size);

 	/* This may be NULL, but that's OK */
+	unset_section_ro_nx(mod, mod->module_init);
 	module_free(mod, mod->module_init);
 	kfree(mod->args);
 	if (mod->percpu)
@@ -1505,6 +1590,7 @@ static void free_module(struct module *mod)
 	lockdep_free_key_range(mod->module_core, mod->core_size);

 	/* Finally, free the core (containing the module structure) */
+	unset_section_ro_nx(mod, mod->module_core);
 	module_free(mod, mod->module_core);
 }

@@ -1678,8 +1764,19 @@ static void layout_sections(struct module *mod,
 			s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
 			DEBUGP("\t%s\n", secstrings + s->sh_name);
 		}
-		if (m == 0)
+		switch (m) {
+		case 0: /* executable */
+			mod->core_size = debug_align(mod->core_size);
 			mod->core_text_size = mod->core_size;
+			break;
+		case 1: /* RO: text and ro-data */
+			mod->core_size = debug_align(mod->core_size);
+			mod->core_ro_size = mod->core_size;
+			break;
+		case 3: /* whole core */
+			mod->core_size = debug_align(mod->core_size);
+			break;
+		}
 	}

 	DEBUGP("Init section allocation order:\n");
@@ -1696,8 +1793,19 @@ static void layout_sections(struct module *mod,
 					 | INIT_OFFSET_MASK);
 			DEBUGP("\t%s\n", secstrings + s->sh_name);
 		}
-		if (m == 0)
+		switch (m) {
+		case 0: /* executable */
+			mod->init_size = debug_align(mod->init_size);
 			mod->init_text_size = mod->init_size;
+			break;
+		case 1: /* RO: text and ro-data */
+			mod->init_size = debug_align(mod->init_size);
+			mod->init_ro_size = mod->init_size;
+			break;
+		case 3: /* whole init */
+			mod->init_size = debug_align(mod->init_size);
+			break;
+		}
 	}
 }

@@ -2291,6 +2399,18 @@ static noinline struct module *load_module(void __user *umod,
 	/* Get rid of temporary copy */
 	vfree(hdr);

+	/* Set RO and NX regions for core */
+	set_section_ro_nx(mod->module_core,
+				mod->core_text_size,
+				mod->core_ro_size,
+				mod->core_size);
+
+	/* Set RO and NX regions for init */
+	set_section_ro_nx(mod->module_init,
+				mod->init_text_size,
+				mod->init_ro_size,
+				mod->init_size);
+
 	/* Done! */
 	return mod;

@@ -2598,6 +2598,7 @@ SYSCALL_DEFINE3(init_module, void __user
 	mutex_lock(&module_mutex);
 	/* Drop initial reference. */
 	module_put(mod);
+	unset_section_ro_nx(mod, mod->module_init);
 	trim_init_extable(mod);
 	module_free(mod, mod->module_init);
 	mod->module_init = NULL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6.31-nx-data.patch:
 kernel/vmlinux.lds.S |    6 +++++-
 mm/init.c            |   22 ++++++++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.31-nx-data.patch ---
Date: 	Thu, 10 Sep 2009 21:10:51 -0400
Message-ID: <817ecb6f0909101810u7774ca93u40a0a4b99f9fb6ba at mail.gmail.com>
Subject: [PATCH V4] x86: NX protection for kernel data
From: Siarhei Liakh <sliakh.lkml at gmail.com>
To: linux-kernel at vger.kernel.org, linux-security-module at vger.kernel.org
Cc: Arjan van de Ven <arjan at infradead.org>, James Morris <jmorris at namei.org>,
        Andrew Morton <akpm at linux-foundation.org>, Andi Kleen <ak at muc.de>,
        Rusty Russell <rusty at rustcorp.com.au>,
        Thomas Gleixner <tglx at linutronix.de>, "H. Peter Anvin" <hpa at zytor.com>,
        Ingo Molnar <mingo at elte.hu>

This patch expands functionality of CONFIG_DEBUG_RODATA to set main
(static) kernel data area as NX.
The following steps are taken to achieve this:
1. Linker script is adjusted so .text always starts and ends on a page boundary
2. Linker script is adjusted so .rodata and .data always start and
end on a page boundary
3. void mark_nxdata_nx(void) added to arch/x86/mm/init.c with actual
functionality: NX is set for all pages from _etext through _end.
4. mark_nxdata_nx() called from free_initmem() (after init has been released)
5. free_init_pages() sets released memory NX in arch/x86/mm/init.c

The patch have been developed for Linux 2.6.31-rc7 x86 by Siarhei Liakh
<sliakh.lkml at gmail.com> and Xuxian Jiang <jiang at cs.ncsu.edu>.

V1:  initial patch for 2.6.30
V2:  patch for 2.6.31-rc7
V3:  moved all code into arch/x86, adjusted credits
V4:  fixed ifdef, removed credits from CREDITS

---

Signed-off-by: Siarhei Liakh <sliakh.lkml at gmail.com>
Signed-off-by: Xuxian Jiang <jiang at cs.ncsu.edu>

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 9fc1782..b6b2bbf 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -43,7 +43,7 @@ jiffies_64 = jiffies;
 
 PHDRS {
 	text PT_LOAD FLAGS(5);          /* R_E */
-	data PT_LOAD FLAGS(7);          /* RWE */
+	data PT_LOAD FLAGS(6);          /* RW_ */
 #ifdef CONFIG_X86_64
 	user PT_LOAD FLAGS(7);          /* RWE */
 #ifdef CONFIG_SMP
@@ -88,6 +88,8 @@ SECTIONS
 		IRQENTRY_TEXT
 		*(.fixup)
 		*(.gnu.warning)
+		/* .text should occupy whole number of pages */
+		. = ALIGN(PAGE_SIZE);
 		/* End of text section */
 		_etext = .;
 	} :text = 0x9090
@@ -128,6 +130,8 @@ SECTIONS
 		/* rarely changed data like cpu maps */
 		READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
 
+		/* .data should occupy whole number of pages */
+		. = ALIGN(PAGE_SIZE);
 		/* End of data section */
 		_edata = .;
 	} :data
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 0607119..522e81b 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -423,9 +423,10 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
 	/*
 	 * We just marked the kernel text read only above, now that
 	 * we are going to free part of that, we need to make that
-	 * writeable first.
+	 * writeable and non-executable first.
 	 */
 	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
+	set_memory_nx(begin, (end - begin) >> PAGE_SHIFT);

 	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);

@@ -440,11 +441,29 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
 #endif
 }

+void mark_nxdata_nx(void)
+{
+#ifdef CONFIG_DEBUG_RODATA
+	/*
+	 * When this called, init has already been executed and released,
+	 * so everything past _etext sould be NX.
+	 */
+	unsigned long start = PFN_ALIGN(_etext);
+	unsigned long size = PFN_ALIGN(_end) - start;
+
+	printk(KERN_INFO "NX-protecting the kernel data: %lx, %lu pages\n",
+		start, size >> PAGE_SHIFT);
+	set_pages_nx(virt_to_page(start), size >> PAGE_SHIFT);
+#endif
+}
+
 void free_initmem(void)
 {
 	free_init_pages("unused kernel memory",
 			(unsigned long)(&__init_begin),
 			(unsigned long)(&__init_end));
+	/* Set kernel's data as NX */
+	mark_nxdata_nx();
 }

 #ifdef CONFIG_BLK_DEV_INITRD
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


drm-nouveau.patch:
 drivers/gpu/drm/Kconfig                     |   45 
 drivers/gpu/drm/Makefile                    |    2 
 drivers/gpu/drm/drm_bufs.c                  |   28 
 drivers/gpu/drm/i2c/Makefile                |    4 
 drivers/gpu/drm/i2c/ch7006_drv.c            |  532 
 drivers/gpu/drm/i2c/ch7006_mode.c           |  473 
 drivers/gpu/drm/i2c/ch7006_priv.h           |  340 
 drivers/gpu/drm/nouveau/Makefile            |   28 
 drivers/gpu/drm/nouveau/nouveau_acpi.c      |  127 
 drivers/gpu/drm/nouveau/nouveau_backlight.c |  155 
 drivers/gpu/drm/nouveau/nouveau_bios.c      | 5209 ++++++
 drivers/gpu/drm/nouveau/nouveau_bios.h      |  235 
 drivers/gpu/drm/nouveau/nouveau_bo.c        |  622 
 drivers/gpu/drm/nouveau/nouveau_calc.c      |  626 
 drivers/gpu/drm/nouveau/nouveau_channel.c   |  537 
 drivers/gpu/drm/nouveau/nouveau_connector.c |  750 
 drivers/gpu/drm/nouveau/nouveau_connector.h |   55 
 drivers/gpu/drm/nouveau/nouveau_crtc.h      |   95 
 drivers/gpu/drm/nouveau/nouveau_display.c   |  115 
 drivers/gpu/drm/nouveau/nouveau_dma.c       |  206 
 drivers/gpu/drm/nouveau/nouveau_dma.h       |  148 
 drivers/gpu/drm/nouveau/nouveau_drv.c       |  433 
 drivers/gpu/drm/nouveau/nouveau_drv.h       | 1218 +
 drivers/gpu/drm/nouveau/nouveau_encoder.h   |   66 
 drivers/gpu/drm/nouveau/nouveau_fb.h        |   47 
 drivers/gpu/drm/nouveau/nouveau_fbcon.c     |  354 
 drivers/gpu/drm/nouveau/nouveau_fbcon.h     |   48 
 drivers/gpu/drm/nouveau/nouveau_fence.c     |  261 
 drivers/gpu/drm/nouveau/nouveau_gem.c       |  954 +
 drivers/gpu/drm/nouveau/nouveau_hw.c        | 1077 +
 drivers/gpu/drm/nouveau/nouveau_hw.h        |  446 
 drivers/gpu/drm/nouveau/nouveau_i2c.c       |  256 
 drivers/gpu/drm/nouveau/nouveau_i2c.h       |   45 
 drivers/gpu/drm/nouveau/nouveau_ioc32.c     |   72 
 drivers/gpu/drm/nouveau/nouveau_irq.c       |  683 
 drivers/gpu/drm/nouveau/nouveau_mem.c       |  565 
 drivers/gpu/drm/nouveau/nouveau_notifier.c  |  194 
 drivers/gpu/drm/nouveau/nouveau_object.c    | 1279 +
 drivers/gpu/drm/nouveau/nouveau_reg.h       |  833 +
 drivers/gpu/drm/nouveau/nouveau_sgdma.c     |  317 
 drivers/gpu/drm/nouveau/nouveau_state.c     |  834 +
 drivers/gpu/drm/nouveau/nouveau_swmthd.h    |   33 
 drivers/gpu/drm/nouveau/nouveau_ttm.c       |  131 
 drivers/gpu/drm/nouveau/nv04_crtc.c         | 1014 +
 drivers/gpu/drm/nouveau/nv04_cursor.c       |   70 
 drivers/gpu/drm/nouveau/nv04_dac.c          |  525 
 drivers/gpu/drm/nouveau/nv04_dfp.c          |  621 
 drivers/gpu/drm/nouveau/nv04_display.c      |  293 
 drivers/gpu/drm/nouveau/nv04_fb.c           |   21 
 drivers/gpu/drm/nouveau/nv04_fbcon.c        |  295 
 drivers/gpu/drm/nouveau/nv04_fifo.c         |  295 
 drivers/gpu/drm/nouveau/nv04_graph.c        |  583 
 drivers/gpu/drm/nouveau/nv04_instmem.c      |  213 
 drivers/gpu/drm/nouveau/nv04_mc.c           |   20 
 drivers/gpu/drm/nouveau/nv04_timer.c        |   51 
 drivers/gpu/drm/nouveau/nv04_tv.c           |  304 
 drivers/gpu/drm/nouveau/nv10_fb.c           |   24 
 drivers/gpu/drm/nouveau/nv10_fifo.c         |  177 
 drivers/gpu/drm/nouveau/nv10_graph.c        |  945 +
 drivers/gpu/drm/nouveau/nv17_tv.c           |  660 
 drivers/gpu/drm/nouveau/nv17_tv.h           |  156 
 drivers/gpu/drm/nouveau/nv17_tv_modes.c     |  582 
 drivers/gpu/drm/nouveau/nv20_graph.c        |  784 
 drivers/gpu/drm/nouveau/nv40_fb.c           |   62 
 drivers/gpu/drm/nouveau/nv40_fifo.c         |  223 
 drivers/gpu/drm/nouveau/nv40_graph.c        | 2214 ++
 drivers/gpu/drm/nouveau/nv40_mc.c           |   38 
 drivers/gpu/drm/nouveau/nv50_crtc.c         |  799 +
 drivers/gpu/drm/nouveau/nv50_cursor.c       |  151 
 drivers/gpu/drm/nouveau/nv50_dac.c          |  296 
 drivers/gpu/drm/nouveau/nv50_display.c      |  905 +
 drivers/gpu/drm/nouveau/nv50_display.h      |   46 
 drivers/gpu/drm/nouveau/nv50_evo.h          |  113 
 drivers/gpu/drm/nouveau/nv50_fbcon.c        |  256 
 drivers/gpu/drm/nouveau/nv50_fifo.c         |  473 
 drivers/gpu/drm/nouveau/nv50_graph.c        |  443 
 drivers/gpu/drm/nouveau/nv50_grctx.h        |22284 ++++++++++++++++++++++++++++
 drivers/gpu/drm/nouveau/nv50_instmem.c      |  499 
 drivers/gpu/drm/nouveau/nv50_mc.c           |   40 
 drivers/gpu/drm/nouveau/nv50_sor.c          |  250 
 drivers/gpu/drm/nouveau/nvreg.h             |  535 
 drivers/gpu/drm/ttm/ttm_bo.c                |    4 
 include/drm/Kbuild                          |    1 
 include/drm/drmP.h                          |    2 
 include/drm/i2c/ch7006.h                    |   86 
 include/drm/nouveau_drm.h                   |  216 
 86 files changed, 58026 insertions(+), 21 deletions(-)

Index: drm-nouveau.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/drm-nouveau.patch,v
retrieving revision 1.8.6.17
retrieving revision 1.8.6.18
diff -u -p -r1.8.6.17 -r1.8.6.18
--- drm-nouveau.patch	10 Sep 2009 14:00:26 -0000	1.8.6.17
+++ drm-nouveau.patch	15 Sep 2009 19:45:37 -0000	1.8.6.18
@@ -1494,10 +1494,10 @@ index 0000000..576bbea
 +#endif
 diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
 new file mode 100644
-index 0000000..5a46cdd
+index 0000000..a4e8223
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/Makefile
-@@ -0,0 +1,27 @@
+@@ -0,0 +1,28 @@
 +#
 +# Makefile for the drm device driver.  This driver provides support for the
 +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
@@ -1523,8 +1523,142 @@ index 0000000..5a46cdd
 +
 +nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
 +nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
++nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
 +
 +obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
+diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
+new file mode 100644
+index 0000000..49514c6
+--- /dev/null
++++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
+@@ -0,0 +1,127 @@
++#include <linux/pci.h>
++#include <linux/acpi.h>
++#include <acpi/acpi_drivers.h>
++#include <acpi/acpi_bus.h>
++
++#include "drmP.h"
++#include "drm.h"
++#include "drm_sarea.h"
++#include "drm_crtc_helper.h"
++#include "nouveau_drv.h"
++#include "nouveau_drm.h"
++#include "nv50_display.h"
++
++#define NOUVEAU_DSM_SUPPORTED 0x00
++#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
++
++#define NOUVEAU_DSM_ACTIVE 0x01
++#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
++
++#define NOUVEAU_DSM_LED 0x02
++#define NOUVEAU_DSM_LED_STATE 0x00
++#define NOUVEAU_DSM_LED_OFF 0x10
++#define NOUVEAU_DSM_LED_STAMINA 0x11
++#define NOUVEAU_DSM_LED_SPEED 0x12
++
++#define NOUVEAU_DSM_POWER 0x03
++#define NOUVEAU_DSM_POWER_STATE 0x00
++#define NOUVEAU_DSM_POWER_SPEED 0x01
++#define NOUVEAU_DSM_POWER_STAMINA 0x02
++
++static int nvidia_dsm(struct pci_dev *dev, int func, int arg, int *result)
++{
++	static char muid[] = {
++		0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
++		0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
++	};
++
++	struct acpi_handle *handle;
++	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
++	struct acpi_object_list input;
++	union acpi_object params[4];
++	union acpi_object *obj;
++	int err;
++
++	handle = DEVICE_ACPI_HANDLE(&dev->dev);
++
++	if (!handle)
++		return -ENODEV;
++
++	input.count = 4;
++	input.pointer = params;
++	params[0].type = ACPI_TYPE_BUFFER;
++	params[0].buffer.length = sizeof(muid);
++	params[0].buffer.pointer = (char *)muid;
++	params[1].type = ACPI_TYPE_INTEGER;
++	params[1].integer.value = 0x00000102;
++	params[2].type = ACPI_TYPE_INTEGER;
++	params[2].integer.value = func;
++	params[3].type = ACPI_TYPE_INTEGER;
++	params[3].integer.value = arg;
++
++	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
++	if (err) {
++		printk(KERN_ERR "nvidia-control: failed to evaluate _DSM: %d\n",
++		       err);
++		return err;
++	}
++
++	obj = (union acpi_object *)output.pointer;
++
++	if (obj->type == ACPI_TYPE_INTEGER)
++		if (obj->integer.value == 0x80000002)
++			return -ENODEV;
++
++	if (obj->type == ACPI_TYPE_BUFFER) {
++		if (obj->buffer.length == 4 && result) {
++			*result = 0;
++			*result |= obj->buffer.pointer[0];
++			*result |= (obj->buffer.pointer[1] << 8);
++			*result |= (obj->buffer.pointer[2] << 16);
++			*result |= (obj->buffer.pointer[3] << 24);
++		}
++	}
++
++	kfree(output.pointer);
++	return 0;
++}
++
++int nouveau_hybrid_setup(struct drm_device *dev)
++{
++	struct pci_dev *pdev = dev->pdev;
++	int result;
++
++	if (nvidia_dsm(pdev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY,
++		       &result))
++		return -ENODEV;
++
++	printk(KERN_INFO "nouveau: _DSM hardware status gave 0x%x\n", result);
++
++	if (result &= 0x1) {	/* Stamina mode - disable the external GPU */
++		nvidia_dsm(pdev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
++			   NULL);
++		nvidia_dsm(pdev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
++			   NULL);
++	} else {		/* Ensure that the external GPU is enabled */
++		nvidia_dsm(pdev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
++		nvidia_dsm(pdev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
++			   NULL);
++	}
++
++	return 0;
++}
++
++bool nouveau_dsm_probe(struct drm_device *dev)
++{
++	struct pci_dev *pdev = dev->pdev;
++	int support = 0;
++
++	if (nvidia_dsm(pdev, NOUVEAU_DSM_SUPPORTED,
++		       NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support))
++		return false;
++
++	if (!support)
++		return false;
++
++	return true;
++}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
 new file mode 100644
 index 0000000..20564f8
@@ -8404,10 +8538,10 @@ index 0000000..3f80db8
 +}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
 new file mode 100644
-index 0000000..7761425
+index 0000000..65810d4
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
-@@ -0,0 +1,520 @@
+@@ -0,0 +1,537 @@
 +/*
 + * Copyright 2005-2006 Stephane Marchesin
 + * All Rights Reserved.
@@ -8522,6 +8656,7 @@ index 0000000..7761425
 +	struct drm_nouveau_private *dev_priv = dev->dev_private;
 +	struct nouveau_engine *engine = &dev_priv->engine;
 +	struct nouveau_channel *chan;
++	unsigned fbdev_flags = 0;
 +	int channel, user;
 +	int ret;
 +
@@ -8611,6 +8746,11 @@ index 0000000..7761425
 +		return ret;
 +	}
 +
++	if (dev_priv->fbdev_info) {
++		fbdev_flags = dev_priv->fbdev_info->flags;
++		dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
 +	engine->graph.fifo_access(dev, false);
 +	nouveau_wait_for_idle(dev);
 +
@@ -8639,25 +8779,24 @@ index 0000000..7761425
 +	 * isn't entirely.. well.. correct.. setup PFIFO ourselves.  For any
 +	 * other case, the GPU will handle this when it switches contexts.
 +	 */
-+	if (dev_priv->engine.fifo.init == nv04_fifo_init ||
-+	    dev_priv->engine.fifo.init == nv40_fifo_init) {
++	if ((dev_priv->engine.fifo.init == nv04_fifo_init ||
++	     dev_priv->engine.fifo.init == nv40_fifo_init) &&
++	    dev_priv->fifo_alloc_count == 1) {
 +		/* setup channel's default get/put values
 +		 */
 +		nvchan_wr32(chan->user_get, chan->pushbuf_base);
 +		nvchan_wr32(chan->user_put, chan->pushbuf_base);
 +
-+		if (dev_priv->fifo_alloc_count == 1) {
-+			ret = engine->fifo.load_context(chan);
-+			if (ret) {
-+				nouveau_channel_free(chan);
-+				return ret;
-+			}
++		ret = engine->fifo.load_context(chan);
++		if (ret) {
++			nouveau_channel_free(chan);
++			return ret;
++		}
 +
-+			ret = engine->graph.load_context(chan);
-+			if (ret) {
-+				nouveau_channel_free(chan);
-+				return ret;
-+			}
++		ret = engine->graph.load_context(chan);
++		if (ret) {
++			nouveau_channel_free(chan);
++			return ret;
 +		}
 +	}
 +
@@ -8672,6 +8811,9 @@ index 0000000..7761425
 +
 +	engine->graph.fifo_access(dev, true);
 +
++	if (dev_priv->fbdev_info)
++		dev_priv->fbdev_info->flags = fbdev_flags;
++
 +	ret = nouveau_dma_init(chan);
 +	if (!ret)
 +		ret = nouveau_fence_init(chan);
@@ -8733,6 +8875,7 @@ index 0000000..7761425
 +	struct drm_device *dev = chan->dev;
 +	struct drm_nouveau_private *dev_priv = dev->dev_private;
 +	struct nouveau_engine *engine = &dev_priv->engine;
++	unsigned fbdev_flags = 0;
 +	uint64_t t_start;
 +	bool timeout = false;
 +	int ret;
@@ -8777,6 +8920,11 @@ index 0000000..7761425
 +	nouveau_fence_fini(chan);
 +
 +	/* disable the fifo caches */
++	if (dev_priv->fbdev_info) {
++		fbdev_flags = dev_priv->fbdev_info->flags;
++		dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
 +	nv_wr32(dev, NV03_PFIFO_CACHES, 0x00000000);
 +	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH,
 +			nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) & ~0x1);
@@ -8795,6 +8943,9 @@ index 0000000..7761425
 +	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 0x00000001);
 +	nv_wr32(dev, NV03_PFIFO_CACHES, 0x00000001);
 +
++	if (dev_priv->fbdev_info)
++		dev_priv->fbdev_info->flags = fbdev_flags;
++
 +	/* Deallocate push buffer */
 +	nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
 +	nouveau_bo_ref(NULL, &chan->pushbuf_bo);
@@ -8930,10 +9081,10 @@ index 0000000..7761425
 +int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
 diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
 new file mode 100644
-index 0000000..7f799f6
+index 0000000..e9577db
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
-@@ -0,0 +1,747 @@
+@@ -0,0 +1,750 @@
 +/*
 + * Copyright (C) 2008 Maarten Maathuis.
 + * All Rights Reserved.
@@ -9329,8 +9480,9 @@ index 0000000..7f799f6
 +};
 +
 +static struct moderec scaler_modes[] = {
-+	{ 1920, 1440 },
-+	{ 1920, 1280 },
++	{ 1920, 1200 },
++	{ 1920, 1080 },
++	{ 1680, 1050 },
 +	{ 1600, 1200 },
 +	{ 1400, 1050 },
 +	{ 1280, 1024 },
@@ -9439,6 +9591,7 @@ index 0000000..7f799f6
 +		    mode->vdisplay > nv_connector->native_mode->vdisplay)
 +			return MODE_PANEL;
 +
++		min_clock = 0;
 +		max_clock = 400000;
 +		break;
 +	case OUTPUT_TMDS:
@@ -9546,7 +9699,8 @@ index 0000000..7f799f6
 +	/* Still nothing, some VBIOS images have a hardcoded EDID block
 +	 * stored for the panel stored in them.
 +	 */
-+	if (!nv_connector->edid && !dev_priv->VBIOS.pub.fp_no_ddc) {
++	if (!nv_connector->edid && !nv_connector->native_mode &&
++	    !dev_priv->VBIOS.pub.fp_no_ddc) {
 +		nv_connector->edid =
 +			(struct edid *)nouveau_bios_embedded_edid(dev);
 +	}
@@ -10771,10 +10925,10 @@ index 0000000..f2b8b17
 +MODULE_LICENSE("GPL and additional rights");
 diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
 new file mode 100644
-index 0000000..57e8db3
+index 0000000..6c9158e
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
-@@ -0,0 +1,1202 @@
+@@ -0,0 +1,1218 @@
 +/*
 + * Copyright 2005 Stephane Marchesin.
 + * All Rights Reserved.
@@ -11343,6 +11497,7 @@ index 0000000..57e8db3
 +	} susres;
 +
 +	struct backlight_device *backlight;
++	bool acpi_dsm;
 +
 +	struct nouveau_channel *evo;
 +
@@ -11530,6 +11685,21 @@ index 0000000..57e8db3
 +extern int  nouveau_dma_init(struct nouveau_channel *);
 +extern int  nouveau_dma_wait(struct nouveau_channel *, int size);
 +
++/* nouveau_acpi.c */
++#ifdef CONFIG_ACPI
++extern int nouveau_hybrid_setup(struct drm_device *dev);
++extern bool nouveau_dsm_probe(struct drm_device *dev);
++#else
++static inline int nouveau_hybrid_setup(struct drm_device *dev)
++{
++	return 0;
++}
++static inline bool nouveau_dsm_probe(struct drm_device *dev)
++{
++	return false;
++}
++#endif
++
 +/* nouveau_backlight.c */
 +#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
 +extern int nouveau_backlight_init(struct drm_device *);
@@ -12104,10 +12274,10 @@ index 0000000..4a3f31a
 +#endif /* __NOUVEAU_FB_H__ */
 diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
 new file mode 100644
-index 0000000..cf772af
+index 0000000..f744723
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-@@ -0,0 +1,355 @@
+@@ -0,0 +1,354 @@
 +/*
 + * Copyright © 2007 David Airlie
 + *
@@ -12188,8 +12358,7 @@ index 0000000..cf772af
 +
 +	ret = -EBUSY;
 +	for (i = 0; i < 100000; i++) {
-+		if (nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)
-+									== 0) {
++		if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) {
 +			ret = 0;
 +			break;
 +		}
@@ -12519,7 +12688,7 @@ index 0000000..0f40414
 +
 diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
 new file mode 100644
-index 0000000..230a99b
+index 0000000..32b4bb9
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
 @@ -0,0 +1,261 @@
@@ -12729,7 +12898,7 @@ index 0000000..230a99b
 +			schedule_timeout(1);
 +
 +		if (intr && signal_pending(current)) {
-+			ret = -ERESTARTSYS;
++			ret = -ERESTART;
 +			break;
 +		}
 +	}
@@ -15672,10 +15841,10 @@ index 0000000..a2c30f4
 +}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
 new file mode 100644
-index 0000000..d3ade09
+index 0000000..a23b2fb
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
-@@ -0,0 +1,675 @@
+@@ -0,0 +1,683 @@
 +/*
 + * Copyright (C) 2006 Ben Skeggs.
 + *
@@ -15812,9 +15981,10 @@ index 0000000..d3ade09
 +	struct drm_nouveau_private *dev_priv = dev->dev_private;
 +	struct nouveau_engine *engine = &dev_priv->engine;
 +	uint32_t status, reassign;
++	int cnt = 0;
 +
 +	reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1;
-+	while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0))) {
++	while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
 +		struct nouveau_channel *chan = NULL;
 +		uint32_t chid, get;
 +
@@ -15891,11 +16061,18 @@ index 0000000..d3ade09
 +			NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
 +				status, chid);
 +			nv_wr32(dev, NV03_PFIFO_INTR_0, status);
++			status = 0;
 +		}
 +
 +		nv_wr32(dev, NV03_PFIFO_CACHES, reassign);
 +	}
 +
++	if (status) {
++		NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt);
++		nv_wr32(dev, 0x2140, 0);
++		nv_wr32(dev, 0x140, 0);
++	}
++
 +	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
 +}
 +
@@ -18409,10 +18586,10 @@ index 0000000..66ab939
 +}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
 new file mode 100644
-index 0000000..4824984
+index 0000000..af9c822
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
-@@ -0,0 +1,834 @@
+@@ -0,0 +1,833 @@
 +
 +
 +#define NV03_BOOT_0                                        0x00100000
@@ -18490,7 +18667,6 @@ index 0000000..4824984
 +#define NV50_USER_DMA_PUT__SIZE                                              128
 +#define NV50_USER_DMA_GET(i)                     (0x00c00044+(i*NV50_USER_SIZE))
 +#define NV50_USER_DMA_GET__SIZE                                              128
-+/*XXX: I don't think this actually exists.. */
 +#define NV50_USER_REF_CNT(i)                     (0x00c00048+(i*NV50_USER_SIZE))
 +#define NV50_USER_REF_CNT__SIZE                                              128
 +
@@ -19572,10 +19748,10 @@ index 0000000..d30c988
 +}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
 new file mode 100644
-index 0000000..b39f11e
+index 0000000..2d62bdc
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_state.c
-@@ -0,0 +1,829 @@
+@@ -0,0 +1,834 @@
 +/*
 + * Copyright 2005 Stephane Marchesin
 + * Copyright 2008 Stuart Bennett
@@ -20119,6 +20295,11 @@ index 0000000..b39f11e
 +	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
 +		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
 +
++	dev_priv->acpi_dsm = nouveau_dsm_probe(dev);
++
++	if (dev_priv->acpi_dsm)
++		nouveau_hybrid_setup(dev);
++
 +	/* resource 0 is mmio regs */
 +	/* resource 1 is linear FB */
 +	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
@@ -23163,10 +23344,10 @@ index 0000000..638cf60
 +}
 diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
 new file mode 100644
-index 0000000..a2046d6
+index 0000000..8915fb3
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
-@@ -0,0 +1,292 @@
+@@ -0,0 +1,295 @@
 +/*
 + * Copyright 2009 Ben Skeggs
 + * Copyright 2008 Stuart Bennett
@@ -23272,14 +23453,17 @@ index 0000000..a2046d6
 +	if (info->state != FBINFO_STATE_RUNNING)
 +		return;
 +
-+	if (image->depth != 1 || info->flags & FBINFO_HWACCEL_DISABLED) {
++	if (image->depth != 1) {
 +		cfb_imageblit(info, image);
 +		return;
 +	}
 +
-+	if (RING_SPACE(chan, 8)) {
++	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) {
 +		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
 +		info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
++	if (info->flags & FBINFO_HWACCEL_DISABLED) {
 +		cfb_imageblit(info, image);
 +		return;
 +	}
@@ -23461,7 +23645,7 @@ index 0000000..a2046d6
 +
 diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
 new file mode 100644
-index 0000000..d9a6b70
+index 0000000..6e984dc
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c
 @@ -0,0 +1,295 @@
@@ -23543,7 +23727,7 @@ index 0000000..d9a6b70
 +			nv_wr32(dev, 0x2230, 0);
 +			nv_wr32(dev, NV40_PFIFO_RAMFC,
 +				((nouveau_mem_fb_amount(dev) - 512 * 1024 +
-+				  dev_priv->ramfc_offset) >> 16) | (2 << 16));
++				  dev_priv->ramfc_offset) >> 16) | (3 << 16));
 +			break;
 +		}
 +		break;
@@ -24351,10 +24535,10 @@ index 0000000..b74d2fc
 +
 diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
 new file mode 100644
-index 0000000..0d1e3e8
+index 0000000..928464e
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
-@@ -0,0 +1,207 @@
+@@ -0,0 +1,213 @@
 +#include "drmP.h"
 +#include "drm.h"
 +#include "nouveau_drv.h"
@@ -24478,12 +24662,18 @@ index 0000000..0d1e3e8
 +	 */
 +	offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
 +
-+	/* On my NV4E, there's *something* clobbering the 16KiB just after
-+	 * where we setup these fixed tables.  No idea what it is just yet,
-+	 * so reserve this space on all NV4X cards for now.
++	/* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
++	 * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
++	 * ("new style" control) the upper 16-bits of 0x2220 points at this
++	 * other mysterious table that's clobbering important things.
++	 *
++	 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
++	 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
 +	 */
-+	if (dev_priv->card_type >= NV_40)
-+		offset += 16*1024;
++	if (dev_priv->card_type >= NV_40) {
++		if (offset < 0x40000)
++			offset = 0x40000;
++	}
 +
 +	ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
 +				    offset, dev_priv->ramin_rsvd_vram - offset);
@@ -28624,10 +28814,10 @@ index 0000000..6b5fdcc
 +}
 diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
 new file mode 100644
-index 0000000..6415e4e
+index 0000000..915fe84
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv40_graph.c
-@@ -0,0 +1,2203 @@
+@@ -0,0 +1,2214 @@
 +/*
 + * Copyright (C) 2007 Ben Skeggs.
 + * All Rights Reserved.
@@ -30144,6 +30334,17 @@ index 0000000..6415e4e
 +void
 +nv40_graph_destroy_context(struct nouveau_channel *chan)
 +{
++	struct drm_device *dev = chan->dev;
++	uint32_t inst;
++
++	/* Mark context as unloaded if still active on PGRAPH */
++	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
++	if (inst & NV40_PGRAPH_CTXCTL_CUR_LOADED) {
++		inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
++		if (inst == (chan->ramin_grctx->instance >> 4))
++			nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
++	}
++
 +	nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx);
 +}
 +
@@ -33223,7 +33424,7 @@ index 0000000..d2f0b80
 +
 diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
 new file mode 100644
-index 0000000..d3807e3
+index 0000000..cc4c2f7
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
 @@ -0,0 +1,256 @@
@@ -33243,15 +33444,14 @@ index 0000000..d3807e3
 +	if (info->state != FBINFO_STATE_RUNNING)
 +		return;
 +
-+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
-+		cfb_fillrect(info, rect);
-+		return;
-+	}
-+
-+	if (RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) {
++	if (!(info->flags & FBINFO_HWACCEL_DISABLED) &&
++	     RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) {
 +		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
 +
 +		info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
++	if (info->flags & FBINFO_HWACCEL_DISABLED) {
 +		cfb_fillrect(info, rect);
 +		return;
 +	}
@@ -33285,15 +33485,13 @@ index 0000000..d3807e3
 +	if (info->state != FBINFO_STATE_RUNNING)
 +		return;
 +
-+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
-+		cfb_copyarea(info, region);
-+		return;
-+	}
-+
-+	if (RING_SPACE(chan, 12)) {
++	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) {
 +		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
 +
 +		info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
++	if (info->flags & FBINFO_HWACCEL_DISABLED) {
 +		cfb_copyarea(info, region);
 +		return;
 +	}
@@ -33327,14 +33525,17 @@ index 0000000..d3807e3
 +	if (info->state != FBINFO_STATE_RUNNING)
 +		return;
 +
-+	if (image->depth != 1 || (info->flags & FBINFO_HWACCEL_DISABLED)) {
++	if (image->depth != 1) {
 +		cfb_imageblit(info, image);
 +		return;
 +	}
 +
-+	if (RING_SPACE(chan, 11)) {
++	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) {
 +		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
 +		info->flags |= FBINFO_HWACCEL_DISABLED;
++	}
++
++	if (info->flags & FBINFO_HWACCEL_DISABLED) {
 +		cfb_imageblit(info, image);
 +		return;
 +	}
@@ -33485,10 +33686,10 @@ index 0000000..d3807e3
 +
 diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
 new file mode 100644
-index 0000000..3d12e12
+index 0000000..6bc0824
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
-@@ -0,0 +1,475 @@
+@@ -0,0 +1,473 @@
 +/*
 + * Copyright (C) 2007 Ben Skeggs.
 + * All Rights Reserved.
@@ -33771,8 +33972,6 @@ index 0000000..3d12e12
 +	nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
 +	nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
 +	nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
-+	nv_wo32(dev, ramfc, 0x50/4, 0x2039b2e0);
-+	nv_wo32(dev, ramfc, 0x54/4, 0x000f0000);
 +	nv_wo32(dev, ramfc, 0x7c/4, 0x30000001);
 +	nv_wo32(dev, ramfc, 0x78/4, 0x00000000);
 +	nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff);
@@ -33966,10 +34165,10 @@ index 0000000..3d12e12
 +
 diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
 new file mode 100644
-index 0000000..108f672
+index 0000000..9a88a1a
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nv50_graph.c
-@@ -0,0 +1,439 @@
+@@ -0,0 +1,443 @@
 +/*
 + * Copyright (C) 2007 Ben Skeggs.
 + * All Rights Reserved.
@@ -34086,9 +34285,11 @@ index 0000000..108f672
 +	case 0xaa:
 +		voodoo = nvaa_ctxprog;
 +		break;
++#if 0 /* block accel for now, it won't work */
 +	case 0xac:
 +		voodoo = nvac_ctxprog;
 +		break;
++#endif
 +	default:
 +		NV_ERROR(dev, "no ctxprog for chipset NV%02x\n", dev_priv->chipset);
 +		dev_priv->engine.graph.accel_blocked = true;
@@ -34207,9 +34408,11 @@ index 0000000..108f672
 +	case 0xaa:
 +		ctxvals = nvaa_ctxvals;
 +		break;
++#if 0 /* block accel for now, it won't work */
 +	case 0xac:
 +		ctxvals = nvac_ctxvals;
 +		break;
++#endif
 +	default:
 +		break;
 +	}


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1294.2.65
retrieving revision 1.1294.2.66
diff -u -p -r1.1294.2.65 -r1.1294.2.66
--- kernel.spec	10 Sep 2009 14:00:29 -0000	1.1294.2.65
+++ kernel.spec	15 Sep 2009 19:45:39 -0000	1.1294.2.66
@@ -665,10 +665,14 @@ Patch610: hda_intel-prealloc-4mb-dmabuff
 Patch611: alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch
 
 Patch670: linux-2.6-ata-quirk.patch
+Patch671: linux-2.6-ahci-export-capabilities.patch
 
 Patch680: linux-2.6-rt2x00-asus-leds.patch
 Patch681: linux-2.6-mac80211-age-scan-results-on-resume.patch
 
+Patch700: linux-2.6.31-nx-data.patch
+Patch701: linux-2.6.31-modules-ro-nx.patch
+
 Patch800: linux-2.6-crash-driver.patch
 
 Patch900: linux-2.6-pci-cacheline-sizing.patch
@@ -724,6 +728,7 @@ Patch2904: v4l-dvb-fix-cx25840-firmware-
 
 # NFSv4
 Patch3050: linux-2.6-nfsd4-proots.patch
+Patch3060: linux-2.6-nfs4-ver4opt.patch
 
 # VIA Nano / VX8xx updates
 Patch11010: via-hwmon-temp-sensor.patch
@@ -731,6 +736,14 @@ Patch11010: via-hwmon-temp-sensor.patch
 # patches headed upstream
 Patch12010: linux-2.6-dell-laptop-rfkill-fix.patch
 Patch12011: linux-2.6-block-silently-error-unsupported-empty-barriers-too.patch
+Patch12012: linux-2.6-rtc-show-hctosys.patch
+Patch12013: linux-2.6-rfkill-all.patch
+
+# patches headed for -stable
+
+# scsi oops fixes
+Patch14000: linux-2.6-scsi-sd-fix-oops-during-scanning.patch
+Patch14001: linux-2.6-scsi-sg-fix-oops-in-error-path.patch
 
 Patch19997: xen.pvops.pre.patch
 Patch19998: xen.pvops.patch
@@ -1211,6 +1224,7 @@ ApplyPatch linux-2.6-execshield.patch
 
 # NFSv4
 ApplyPatch linux-2.6-nfsd4-proots.patch
+ApplyPatch linux-2.6-nfs4-ver4opt.patch
 
 # USB
 ApplyPatch linux-2.6-driver-level-usb-autosuspend.diff
@@ -1289,12 +1303,20 @@ ApplyPatch linux-2.6-silence-fbcon-logo.
 # ia64 ata quirk
 ApplyPatch linux-2.6-ata-quirk.patch
 
+# Make it possible to identify non-hotplug SATA ports
+ApplyPatch linux-2.6-ahci-export-capabilities.patch
+
 # rt2x00: back-port activity LED init patches
 #ApplyPatch linux-2.6-rt2x00-asus-leds.patch
 
 # back-port scan result aging patches
 #ApplyPatch linux-2.6-mac80211-age-scan-results-on-resume.patch
 
+# Mark kernel data as NX
+ApplyPatch linux-2.6.31-nx-data.patch
+# Apply NX/RO to modules
+ApplyPatch linux-2.6.31-modules-ro-nx.patch
+
 # /dev/crash driver.
 ApplyPatch linux-2.6-crash-driver.patch
 
@@ -1359,6 +1381,14 @@ ApplyPatch linux-2.6-silence-acpi-blackl
 ApplyPatch v4l-dvb-fix-cx25840-firmware-loading.patch
 
 # Patches headed upstream
+ApplyPatch linux-2.6-rtc-show-hctosys.patch
+ApplyPatch linux-2.6-rfkill-all.patch
+
+# patches headed for -stable
+
+# scsi oops fixes
+ApplyPatch linux-2.6-scsi-sd-fix-oops-during-scanning.patch
+ApplyPatch linux-2.6-scsi-sg-fix-oops-in-error-path.patch
 
 ApplyPatch xen.pvops.pre.patch
 ApplyPatch xen.pvops.patch
@@ -2019,6 +2049,42 @@ fi
 # and build.
 
 %changelog
+* Tue Sep 15 2009 Michael Young <m.a.young at durham.ac.uk>
+- switch to the F-12 branch for the moment
+
+* Tue Sep 15 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: misc fixes to context-related issues, fixes some severe nv4x bugs
+
+* Tue Sep 15 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: temporarily disable fbcon accel, it's racing with ttm
+
+* Mon Sep 14 2009 Steve Dickson <steved at redhat.com>
+- Added support for -o v4 mount parsing
+
+* Mon Sep 14 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: avoid PFIFO IRQ hardlock, misc LVDS mode fixes, nv5x RAMFC cleanup
+
+* Sun Sep 13 2009 Chuck Ebbert <cebbert at redhat.com>
+- SCSI oops fixes requested for -stable
+
+* Fri Sep 11 2009 Dave Jones <davej at redhat.com>
+- Apply NX/RO to modules
+
+* Fri Sep 11 2009 Dave Jones <davej at redhat.com>
+- Mark kernel data section as NX
+
+* Fri Sep 11 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: bring in Matthew Garret's initial switchable graphics support
+
+* Fri Sep 11 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: fixed use of strap-based panel mode when required (rh#522649)
+- nouveau: temporarily block accel on NVAC chipsets (rh#522361, rh#522575)
+
+* Thu Sep 10 2009 Matthew Garrett <mjg at redhat.com>
+- linux-2.6-ahci-export-capabilities.patch: Backport from upstream
+- linux-2.6-rtc-show-hctosys.patch: Export the hctosys state of an rtc
+- linux-2.6-rfkill-all.patch: Support for keys that toggle all rfkill state
+
 * Thu Sep 10 2009 Michael Young <m.a.young at durham.ac.uk>
 - update pvops and get to 2.6.31
 

xen.pvops.patch:
 arch/x86/Kconfig                           |    4 
 arch/x86/Makefile                          |    2 
 arch/x86/include/asm/agp.h                 |   15 
 arch/x86/include/asm/e820.h                |    2 
 arch/x86/include/asm/i387.h                |    1 
 arch/x86/include/asm/io.h                  |   15 
 arch/x86/include/asm/io_apic.h             |    7 
 arch/x86/include/asm/microcode.h           |    9 
 arch/x86/include/asm/paravirt.h            |  718 ------------
 arch/x86/include/asm/paravirt_types.h      |  722 +++++++++++++
 arch/x86/include/asm/pci.h                 |    8 
 arch/x86/include/asm/pci_x86.h             |    2 
 arch/x86/include/asm/pgtable.h             |    3 
 arch/x86/include/asm/processor.h           |    4 
 arch/x86/include/asm/tlbflush.h            |    6 
 arch/x86/include/asm/xen/hypercall.h       |   44 
 arch/x86/include/asm/xen/interface.h       |    8 
 arch/x86/include/asm/xen/interface_32.h    |    5 
 arch/x86/include/asm/xen/interface_64.h    |   13 
 arch/x86/include/asm/xen/iommu.h           |   12 
 arch/x86/include/asm/xen/page.h            |   16 
 arch/x86/include/asm/xen/pci.h             |   37 
 arch/x86/include/asm/xen/swiotlb.h         |   12 
 arch/x86/kernel/Makefile                   |    1 
 arch/x86/kernel/acpi/boot.c                |   18 
 arch/x86/kernel/acpi/processor.c           |    4 
 arch/x86/kernel/acpi/sleep.c               |    2 
 arch/x86/kernel/apic/io_apic.c             |   49 
 arch/x86/kernel/cpu/mtrr/Makefile          |    1 
 arch/x86/kernel/cpu/mtrr/amd.c             |    6 
 arch/x86/kernel/cpu/mtrr/centaur.c         |    6 
 arch/x86/kernel/cpu/mtrr/cyrix.c           |    6 
 arch/x86/kernel/cpu/mtrr/generic.c         |   10 
 arch/x86/kernel/cpu/mtrr/main.c            |   19 
 arch/x86/kernel/cpu/mtrr/mtrr.h            |   11 
 arch/x86/kernel/cpu/mtrr/xen.c             |  104 +
 arch/x86/kernel/e820.c                     |   30 
 arch/x86/kernel/ioport.c                   |   29 
 arch/x86/kernel/microcode_core.c           |    5 
 arch/x86/kernel/microcode_xen.c            |  200 +++
 arch/x86/kernel/paravirt.c                 |    1 
 arch/x86/kernel/pci-dma.c                  |    8 
 arch/x86/kernel/pci-swiotlb.c              |   25 
 arch/x86/kernel/process.c                  |   27 
 arch/x86/kernel/process_32.c               |   27 
 arch/x86/kernel/process_64.c               |   33 
 arch/x86/kernel/setup.c                    |    4 
 arch/x86/kernel/traps.c                    |   33 
 arch/x86/mm/Makefile                       |    6 
 arch/x86/mm/init_32.c                      |   42 
 arch/x86/mm/ioremap.c                      |   72 -
 arch/x86/mm/pat.c                          |    2 
 arch/x86/mm/pgtable.c                      |   10 
 arch/x86/mm/physaddr.c                     |   70 +
 arch/x86/mm/physaddr.h                     |   10 
 arch/x86/mm/tlb.c                          |   35 
 arch/x86/pci/Makefile                      |    1 
 arch/x86/pci/common.c                      |   18 
 arch/x86/pci/i386.c                        |    3 
 arch/x86/pci/init.c                        |    6 
 arch/x86/pci/xen.c                         |   51 
 arch/x86/xen/Kconfig                       |   33 
 arch/x86/xen/Makefile                      |    5 
 arch/x86/xen/apic.c                        |   57 +
 arch/x86/xen/enlighten.c                   |  202 +++
 arch/x86/xen/mmu.c                         |  455 ++++++++
 arch/x86/xen/pci-swiotlb.c                 |  988 +++++++++++++++++
 arch/x86/xen/pci.c                         |  111 ++
 arch/x86/xen/setup.c                       |   50 
 arch/x86/xen/smp.c                         |    3 
 arch/x86/xen/spinlock.c                    |   28 
 arch/x86/xen/time.c                        |    2 
 arch/x86/xen/vga.c                         |   67 +
 arch/x86/xen/xen-ops.h                     |   19 
 block/blk-core.c                           |    2 
 drivers/acpi/acpica/hwsleep.c              |   17 
 drivers/acpi/processor_core.c              |   29 
 drivers/acpi/processor_idle.c              |   23 
 drivers/acpi/processor_perflib.c           |   10 
 drivers/acpi/sleep.c                       |   19 
 drivers/block/Kconfig                      |    1 
 drivers/char/agp/intel-agp.c               |   17 
 drivers/char/hvc_xen.c                     |   99 +
 drivers/net/Kconfig                        |    1 
 drivers/pci/Makefile                       |    2 
 drivers/pci/xen-iommu.c                    |  271 ++++
 drivers/xen/Kconfig                        |   41 
 drivers/xen/Makefile                       |   23 
 drivers/xen/acpi.c                         |   23 
 drivers/xen/acpi_processor.c               |  451 ++++++++
 drivers/xen/balloon.c                      |  161 ++
 drivers/xen/biomerge.c                     |   14 
 drivers/xen/blkback/Makefile               |    3 
 drivers/xen/blkback/blkback.c              |  657 +++++++++++
 drivers/xen/blkback/common.h               |  137 ++
 drivers/xen/blkback/interface.c            |  182 +++
 drivers/xen/blkback/vbd.c                  |  118 ++
 drivers/xen/blkback/xenbus.c               |  542 +++++++++
 drivers/xen/events.c                       |  422 +++++++
 drivers/xen/evtchn.c                       |    1 
 drivers/xen/features.c                     |    2 
 drivers/xen/grant-table.c                  |  103 +
 drivers/xen/mce.c                          |  213 +++
 drivers/xen/netback/Makefile               |    3 
 drivers/xen/netback/common.h               |  221 ++++
 drivers/xen/netback/interface.c            |  401 +++++++
 drivers/xen/netback/netback.c              | 1602 +++++++++++++++++++++++++++++
 drivers/xen/netback/xenbus.c               |  454 ++++++++
 drivers/xen/pci.c                          |  124 ++
 drivers/xen/xenbus/Makefile                |    5 
 drivers/xen/xenbus/xenbus_comms.c          |    1 
 drivers/xen/xenbus/xenbus_probe.c          |  380 +-----
 drivers/xen/xenbus/xenbus_probe.h          |   29 
 drivers/xen/xenbus/xenbus_probe_backend.c  |  298 +++++
 drivers/xen/xenbus/xenbus_probe_frontend.c |  292 +++++
 drivers/xen/xenfs/Makefile                 |    3 
 drivers/xen/xenfs/privcmd.c                |  403 +++++++
 drivers/xen/xenfs/super.c                  |   98 +
 drivers/xen/xenfs/xenfs.h                  |    3 
 drivers/xen/xenfs/xenstored.c              |   67 +
 include/acpi/processor.h                   |    2 
 include/asm-generic/pci.h                  |    2 
 include/linux/interrupt.h                  |    1 
 include/linux/page-flags.h                 |   18 
 include/xen/Kbuild                         |    1 
 include/xen/acpi.h                         |   84 +
 include/xen/balloon.h                      |    8 
 include/xen/blkif.h                        |  122 ++
 include/xen/events.h                       |   27 
 include/xen/grant_table.h                  |   43 
 include/xen/interface/grant_table.h        |   22 
 include/xen/interface/memory.h             |   92 +
 include/xen/interface/physdev.h            |   51 
 include/xen/interface/platform.h           |  336 ++++++
 include/xen/interface/xen-mca.h            |  429 +++++++
 include/xen/interface/xen.h                |   44 
 include/xen/privcmd.h                      |   80 +
 include/xen/swiotlb.h                      |  102 +
 include/xen/xen-ops.h                      |   11 
 include/xen/xenbus.h                       |    2 
 kernel/irq/manage.c                        |    3 
 lib/swiotlb.c                              |    5 
 mm/page_alloc.c                            |   14 
 143 files changed, 12716 insertions(+), 1421 deletions(-)

Index: xen.pvops.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/Attic/xen.pvops.patch,v
retrieving revision 1.1.2.41
retrieving revision 1.1.2.42
diff -u -p -r1.1.2.41 -r1.1.2.42
--- xen.pvops.patch	10 Sep 2009 14:00:31 -0000	1.1.2.41
+++ xen.pvops.patch	15 Sep 2009 19:45:40 -0000	1.1.2.42
@@ -3230,20 +3230,20 @@ index 5204332..22a5a6d 100644
  EXPORT_SYMBOL_GPL(math_state_restore);
  
 diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
-index eefdeee..72bb3a2 100644
+index eefdeee..9b5a9f5 100644
 --- a/arch/x86/mm/Makefile
 +++ b/arch/x86/mm/Makefile
-@@ -1,6 +1,10 @@
+@@ -1,5 +1,9 @@
  obj-y	:=  init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
- 	    pat.o pgtable.o gup.o
- 
+-	    pat.o pgtable.o gup.o
++	    pat.o pgtable.o physaddr.o gup.o
++
 +# Make sure __phys_addr has no stackprotector
 +nostackp := $(call cc-option, -fno-stack-protector)
-+CFLAGS_ioremap.o		:= $(nostackp)
-+
++CFLAGS_physaddr.o		:= $(nostackp)
+ 
  obj-$(CONFIG_SMP)		+= tlb.o
  
- obj-$(CONFIG_X86_32)		+= pgtable_32.o iomap_32.o
 diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
 index 3cd7711..f16903d 100644
 --- a/arch/x86/mm/init_32.c
@@ -3311,6 +3311,89 @@ index 3cd7711..f16903d 100644
  	work_with_active_regions(nid, add_highpages_work_fn, &data);
  }
  
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 8a45093..04e1ad6 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -22,77 +22,7 @@
+ #include <asm/pgalloc.h>
+ #include <asm/pat.h>
+ 
+-static inline int phys_addr_valid(resource_size_t addr)
+-{
+-#ifdef CONFIG_PHYS_ADDR_T_64BIT
+-	return !(addr >> boot_cpu_data.x86_phys_bits);
+-#else
+-	return 1;
+-#endif
+-}
+-
+-#ifdef CONFIG_X86_64
+-
+-unsigned long __phys_addr(unsigned long x)
+-{
+-	if (x >= __START_KERNEL_map) {
+-		x -= __START_KERNEL_map;
+-		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
+-		x += phys_base;
+-	} else {
+-		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+-		x -= PAGE_OFFSET;
+-		VIRTUAL_BUG_ON(!phys_addr_valid(x));
+-	}
+-	return x;
+-}
+-EXPORT_SYMBOL(__phys_addr);
+-
+-bool __virt_addr_valid(unsigned long x)
+-{
+-	if (x >= __START_KERNEL_map) {
+-		x -= __START_KERNEL_map;
+-		if (x >= KERNEL_IMAGE_SIZE)
+-			return false;
+-		x += phys_base;
+-	} else {
+-		if (x < PAGE_OFFSET)
+-			return false;
+-		x -= PAGE_OFFSET;
+-		if (!phys_addr_valid(x))
+-			return false;
+-	}
+-
+-	return pfn_valid(x >> PAGE_SHIFT);
+-}
+-EXPORT_SYMBOL(__virt_addr_valid);
+-
+-#else
+-
+-#ifdef CONFIG_DEBUG_VIRTUAL
+-unsigned long __phys_addr(unsigned long x)
+-{
+-	/* VMALLOC_* aren't constants  */
+-	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+-	VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
+-	return x - PAGE_OFFSET;
+-}
+-EXPORT_SYMBOL(__phys_addr);
+-#endif
+-
+-bool __virt_addr_valid(unsigned long x)
+-{
+-	if (x < PAGE_OFFSET)
+-		return false;
+-	if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
+-		return false;
+-	if (x >= FIXADDR_START)
+-		return false;
+-	return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
+-}
+-EXPORT_SYMBOL(__virt_addr_valid);
+-
+-#endif
++#include "physaddr.h"
+ 
+ int page_is_ram(unsigned long pagenr)
+ {
 diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
 index 352aa9e..95609e3 100644
 --- a/arch/x86/mm/pat.c
@@ -3345,6 +3428,98 @@ index ed34f5e..9c58425 100644
  pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
  {
  	return (pte_t *)__get_free_page(PGALLOC_GFP);
+diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c
+new file mode 100644
+index 0000000..d2e2735
+--- /dev/null
++++ b/arch/x86/mm/physaddr.c
+@@ -0,0 +1,70 @@
++#include <linux/mmdebug.h>
++#include <linux/module.h>
++#include <linux/mm.h>
++
++#include <asm/page.h>
++
++#include "physaddr.h"
++
++#ifdef CONFIG_X86_64
++
++unsigned long __phys_addr(unsigned long x)
++{
++	if (x >= __START_KERNEL_map) {
++		x -= __START_KERNEL_map;
++		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
++		x += phys_base;
++	} else {
++		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
++		x -= PAGE_OFFSET;
++		VIRTUAL_BUG_ON(!phys_addr_valid(x));
++	}
++	return x;
++}
++EXPORT_SYMBOL(__phys_addr);
++
++bool __virt_addr_valid(unsigned long x)
++{
++	if (x >= __START_KERNEL_map) {
++		x -= __START_KERNEL_map;
++		if (x >= KERNEL_IMAGE_SIZE)
++			return false;
++		x += phys_base;
++	} else {
++		if (x < PAGE_OFFSET)
++			return false;
++		x -= PAGE_OFFSET;
++		if (!phys_addr_valid(x))
++			return false;
++	}
++
++	return pfn_valid(x >> PAGE_SHIFT);
++}
++EXPORT_SYMBOL(__virt_addr_valid);
++
++#else
++
++#ifdef CONFIG_DEBUG_VIRTUAL
++unsigned long __phys_addr(unsigned long x)
++{
++	/* VMALLOC_* aren't constants  */
++	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
++	VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
++	return x - PAGE_OFFSET;
++}
++EXPORT_SYMBOL(__phys_addr);
++#endif
++
++bool __virt_addr_valid(unsigned long x)
++{
++	if (x < PAGE_OFFSET)
++		return false;
++	if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
++		return false;
++	if (x >= FIXADDR_START)
++		return false;
++	return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
++}
++EXPORT_SYMBOL(__virt_addr_valid);
++
++#endif	/* CONFIG_X86_64 */
+diff --git a/arch/x86/mm/physaddr.h b/arch/x86/mm/physaddr.h
+new file mode 100644
+index 0000000..a3cd5a0
+--- /dev/null
++++ b/arch/x86/mm/physaddr.h
+@@ -0,0 +1,10 @@
++#include <asm/processor.h>
++
++static inline int phys_addr_valid(resource_size_t addr)
++{
++#ifdef CONFIG_PHYS_ADDR_T_64BIT
++	return !(addr >> boot_cpu_data.x86_phys_bits);
++#else
++	return 1;
++#endif
++}
 diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
 index c814e14..f68d42f 100644
 --- a/arch/x86/mm/tlb.c




More information about the fedora-extras-commits mailing list