drm/nv50: fix iommu errors caused by device reading from address 0
[safe/jmp/linux-2.6] / drivers / xen / sys-hypervisor.c
index cb29d1c..60f1827 100644 (file)
@@ -7,6 +7,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
@@ -14,6 +15,7 @@
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>
@@ -293,37 +295,48 @@ static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
 
 HYPERVISOR_ATTR_RO(pagesize);
 
-/* eventually there will be several more features to export */
 static ssize_t xen_feature_show(int index, char *buffer)
 {
-       int ret = -ENOMEM;
-       struct xen_feature_info *info;
+       ssize_t ret;
+       struct xen_feature_info info;
 
-       info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
-       if (info) {
-               info->submap_idx = index;
-               ret = HYPERVISOR_xen_version(XENVER_get_features, info);
-               if (!ret)
-                       ret = sprintf(buffer, "%d\n", info->submap);
-               kfree(info);
-       }
+       info.submap_idx = index;
+       ret = HYPERVISOR_xen_version(XENVER_get_features, &info);
+       if (!ret)
+               ret = sprintf(buffer, "%08x", info.submap);
 
        return ret;
 }
 
-static ssize_t writable_pt_show(struct hyp_sysfs_attr *attr, char *buffer)
+static ssize_t features_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       return xen_feature_show(XENFEAT_writable_page_tables, buffer);
+       ssize_t len;
+       int i;
+
+       len = 0;
+       for (i = XENFEAT_NR_SUBMAPS-1; i >= 0; i--) {
+               int ret = xen_feature_show(i, buffer + len);
+               if (ret < 0) {
+                       if (len == 0)
+                               len = ret;
+                       break;
+               }
+               len += ret;
+       }
+       if (len > 0)
+               buffer[len++] = '\n';
+
+       return len;
 }
 
-HYPERVISOR_ATTR_RO(writable_pt);
+HYPERVISOR_ATTR_RO(features);
 
 static struct attribute *xen_properties_attrs[] = {
        &capabilities_attr.attr,
        &changeset_attr.attr,
        &virtual_start_attr.attr,
        &pagesize_attr.attr,
-       &writable_pt_attr.attr,
+       &features_attr.attr,
        NULL
 };
 
@@ -342,32 +355,6 @@ static void xen_properties_destroy(void)
        sysfs_remove_group(hypervisor_kobj, &xen_properties_group);
 }
 
-#ifdef CONFIG_KEXEC
-
-extern size_t vmcoreinfo_size_xen;
-extern unsigned long paddr_vmcoreinfo_xen;
-
-static ssize_t vmcoreinfo_show(struct hyp_sysfs_attr *attr, char *page)
-{
-       return sprintf(page, "%lx %zx\n",
-               paddr_vmcoreinfo_xen, vmcoreinfo_size_xen);
-}
-
-HYPERVISOR_ATTR_RO(vmcoreinfo);
-
-static int __init xen_sysfs_vmcoreinfo_init(void)
-{
-       return sysfs_create_file(hypervisor_kobj,
-                                &vmcoreinfo_attr.attr);
-}
-
-static void xen_sysfs_vmcoreinfo_destroy(void)
-{
-       sysfs_remove_file(hypervisor_kobj, &vmcoreinfo_attr.attr);
-}
-
-#endif
-
 static int __init hyper_sysfs_init(void)
 {
        int ret;
@@ -390,20 +377,9 @@ static int __init hyper_sysfs_init(void)
        ret = xen_properties_init();
        if (ret)
                goto prop_out;
-#ifdef CONFIG_KEXEC
-       if (vmcoreinfo_size_xen != 0) {
-               ret = xen_sysfs_vmcoreinfo_init();
-               if (ret)
-                       goto vmcoreinfo_out;
-       }
-#endif
 
        goto out;
 
-#ifdef CONFIG_KEXEC
-vmcoreinfo_out:
-#endif
-       xen_properties_destroy();
 prop_out:
        xen_sysfs_uuid_destroy();
 uuid_out:
@@ -418,10 +394,6 @@ out:
 
 static void __exit hyper_sysfs_exit(void)
 {
-#ifdef CONFIG_KEXEC
-       if (vmcoreinfo_size_xen != 0)
-               xen_sysfs_vmcoreinfo_destroy();
-#endif
        xen_properties_destroy();
        xen_compilation_destroy();
        xen_sysfs_uuid_destroy();
@@ -455,7 +427,7 @@ static ssize_t hyp_sysfs_store(struct kobject *kobj,
        return 0;
 }
 
-static struct sysfs_ops hyp_sysfs_ops = {
+static const struct sysfs_ops hyp_sysfs_ops = {
        .show = hyp_sysfs_show,
        .store = hyp_sysfs_store,
 };