~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/platform/efi/runtime-map.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung@redhat.com>
  4  */
  5 
  6 #include <linux/string.h>
  7 #include <linux/kernel.h>
  8 #include <linux/module.h>
  9 #include <linux/types.h>
 10 #include <linux/efi.h>
 11 #include <linux/slab.h>
 12 
 13 #include <asm/efi.h>
 14 #include <asm/setup.h>
 15 
 16 struct efi_runtime_map_entry {
 17         efi_memory_desc_t md;
 18         struct kobject kobj;   /* kobject for each entry */
 19 };
 20 
 21 static struct efi_runtime_map_entry **map_entries;
 22 
 23 struct map_attribute {
 24         struct attribute attr;
 25         ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
 26 };
 27 
 28 static inline struct map_attribute *to_map_attr(struct attribute *attr)
 29 {
 30         return container_of(attr, struct map_attribute, attr);
 31 }
 32 
 33 static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
 34 {
 35         return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
 36 }
 37 
 38 #define EFI_RUNTIME_FIELD(var) entry->md.var
 39 
 40 #define EFI_RUNTIME_U64_ATTR_SHOW(name) \
 41 static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
 42 { \
 43         return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
 44 }
 45 
 46 EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
 47 EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
 48 EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
 49 EFI_RUNTIME_U64_ATTR_SHOW(attribute);
 50 
 51 static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
 52 {
 53         return container_of(kobj, struct efi_runtime_map_entry, kobj);
 54 }
 55 
 56 static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
 57                               char *buf)
 58 {
 59         struct efi_runtime_map_entry *entry = to_map_entry(kobj);
 60         struct map_attribute *map_attr = to_map_attr(attr);
 61 
 62         return map_attr->show(entry, buf);
 63 }
 64 
 65 static struct map_attribute map_type_attr = __ATTR_RO_MODE(type, 0400);
 66 static struct map_attribute map_phys_addr_attr = __ATTR_RO_MODE(phys_addr, 0400);
 67 static struct map_attribute map_virt_addr_attr = __ATTR_RO_MODE(virt_addr, 0400);
 68 static struct map_attribute map_num_pages_attr = __ATTR_RO_MODE(num_pages, 0400);
 69 static struct map_attribute map_attribute_attr = __ATTR_RO_MODE(attribute, 0400);
 70 
 71 /*
 72  * These are default attributes that are added for every memmap entry.
 73  */
 74 static struct attribute *def_attrs[] = {
 75         &map_type_attr.attr,
 76         &map_phys_addr_attr.attr,
 77         &map_virt_addr_attr.attr,
 78         &map_num_pages_attr.attr,
 79         &map_attribute_attr.attr,
 80         NULL
 81 };
 82 ATTRIBUTE_GROUPS(def);
 83 
 84 static const struct sysfs_ops map_attr_ops = {
 85         .show = map_attr_show,
 86 };
 87 
 88 static void map_release(struct kobject *kobj)
 89 {
 90         struct efi_runtime_map_entry *entry;
 91 
 92         entry = to_map_entry(kobj);
 93         kfree(entry);
 94 }
 95 
 96 static const struct kobj_type __refconst map_ktype = {
 97         .sysfs_ops      = &map_attr_ops,
 98         .default_groups = def_groups,
 99         .release        = map_release,
100 };
101 
102 static struct kset *map_kset;
103 
104 static struct efi_runtime_map_entry *
105 add_sysfs_runtime_map_entry(struct kobject *kobj, int nr,
106                             efi_memory_desc_t *md)
107 {
108         int ret;
109         struct efi_runtime_map_entry *entry;
110 
111         if (!map_kset) {
112                 map_kset = kset_create_and_add("runtime-map", NULL, kobj);
113                 if (!map_kset)
114                         return ERR_PTR(-ENOMEM);
115         }
116 
117         entry = kzalloc(sizeof(*entry), GFP_KERNEL);
118         if (!entry) {
119                 kset_unregister(map_kset);
120                 map_kset = NULL;
121                 return ERR_PTR(-ENOMEM);
122         }
123 
124         memcpy(&entry->md, md, sizeof(efi_memory_desc_t));
125 
126         kobject_init(&entry->kobj, &map_ktype);
127         entry->kobj.kset = map_kset;
128         ret = kobject_add(&entry->kobj, NULL, "%d", nr);
129         if (ret) {
130                 kobject_put(&entry->kobj);
131                 kset_unregister(map_kset);
132                 map_kset = NULL;
133                 return ERR_PTR(ret);
134         }
135 
136         return entry;
137 }
138 
139 int efi_get_runtime_map_size(void)
140 {
141         return efi.memmap.nr_map * efi.memmap.desc_size;
142 }
143 
144 int efi_get_runtime_map_desc_size(void)
145 {
146         return efi.memmap.desc_size;
147 }
148 
149 int efi_runtime_map_copy(void *buf, size_t bufsz)
150 {
151         size_t sz = efi_get_runtime_map_size();
152 
153         if (sz > bufsz)
154                 sz = bufsz;
155 
156         memcpy(buf, efi.memmap.map, sz);
157         return 0;
158 }
159 
160 static int __init efi_runtime_map_init(void)
161 {
162         int i, j, ret = 0;
163         struct efi_runtime_map_entry *entry;
164         efi_memory_desc_t *md;
165 
166         if (!efi_enabled(EFI_MEMMAP) || !efi_kobj)
167                 return 0;
168 
169         map_entries = kcalloc(efi.memmap.nr_map, sizeof(entry), GFP_KERNEL);
170         if (!map_entries) {
171                 ret = -ENOMEM;
172                 goto out;
173         }
174 
175         i = 0;
176         for_each_efi_memory_desc(md) {
177                 entry = add_sysfs_runtime_map_entry(efi_kobj, i, md);
178                 if (IS_ERR(entry)) {
179                         ret = PTR_ERR(entry);
180                         goto out_add_entry;
181                 }
182                 *(map_entries + i++) = entry;
183         }
184 
185         return 0;
186 out_add_entry:
187         for (j = i - 1; j >= 0; j--) {
188                 entry = *(map_entries + j);
189                 kobject_put(&entry->kobj);
190         }
191 out:
192         return ret;
193 }
194 subsys_initcall_sync(efi_runtime_map_init);
195 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php