efi_loader: helper function to add EFI object to list
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Sun, 26 Nov 2017 13:05:23 +0000 (14:05 +0100)
committerAlexander Graf <agraf@suse.de>
Fri, 1 Dec 2017 12:41:01 +0000 (13:41 +0100)
To avoid duplicate coding provide a helper function that
initializes an EFI object and adds it to the EFI object
list.

efi_exit() is the only place where we dereference a handle
to obtain a protocol interface. Add a comment to the function.

Suggested-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
include/efi_loader.h
lib/efi_loader/efi_boottime.c
lib/efi_loader/efi_disk.c
lib/efi_loader/efi_gop.c
lib/efi_loader/efi_net.c

index a73bbc126952057975d4808d1de0d06949199ddf..c0caabddb122e696930170f6315bd153b57ede1b 100644 (file)
@@ -186,6 +186,8 @@ void efi_restore_gd(void);
 void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map);
 /* Call this to set the current device name */
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
+/* Add a new object to the object list. */
+void efi_add_handle(struct efi_object *obj);
 /* Create handle */
 efi_status_t efi_create_handle(void **handle);
 /* Call this to validate a handle and find the EFI object for it */
index 0fb2848ecf9a70b6b8f0eaff472106ca695f2526..a37fb25638ce35aea864a6d7c0ae92b18bdaaafd 100644 (file)
@@ -321,6 +321,23 @@ static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
        return EFI_EXIT(r);
 }
 
+/*
+ * Add a new object to the object list.
+ *
+ * The protocols list is initialized.
+ * The object handle is set.
+ *
+ * @obj        object to be added
+ */
+void efi_add_handle(struct efi_object *obj)
+{
+       if (!obj)
+               return;
+       INIT_LIST_HEAD(&obj->protocols);
+       obj->handle = obj;
+       list_add_tail(&obj->link, &efi_obj_list);
+}
+
 /*
  * Create handle.
  *
@@ -337,11 +354,8 @@ efi_status_t efi_create_handle(void **handle)
                              (void **)&obj);
        if (r != EFI_SUCCESS)
                return r;
-       memset(obj, 0, sizeof(struct efi_object));
-       obj->handle = obj;
-       INIT_LIST_HEAD(&obj->protocols);
-       list_add_tail(&obj->link, &efi_obj_list);
-       *handle = obj;
+       efi_add_handle(obj);
+       *handle = obj->handle;
        return r;
 }
 
@@ -1163,14 +1177,15 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob
 {
        efi_status_t ret;
 
+       /* Add internal object to object list */
+       efi_add_handle(obj);
+       /* efi_exit() assumes that the handle points to the info */
        obj->handle = info;
 
        info->file_path = file_path;
        if (device_path)
                info->device_handle = efi_dp_find_obj(device_path, NULL);
 
-       INIT_LIST_HEAD(&obj->protocols);
-       list_add_tail(&obj->link, &efi_obj_list);
        /*
         * When asking for the device path interface, return
         * bootefi_device_path
@@ -1379,6 +1394,17 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
                        efi_status_t exit_status, unsigned long exit_data_size,
                        int16_t *exit_data)
 {
+       /*
+        * We require that the handle points to the original loaded
+        * image protocol interface.
+        *
+        * For getting the longjmp address this is safer than locating
+        * the protocol because the protocol may have been reinstalled
+        * pointing to another memory location.
+        *
+        * TODO: We should call the unload procedure of the loaded
+        *       image protocol.
+        */
        struct efi_loaded_image *loaded_image_info = (void*)image_handle;
 
        EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
index af8db40e19ba112977e54690cec2e86bb5fd7d58..68ba2cf7b2add774d8455f50cab7f44180d234e4 100644 (file)
@@ -224,13 +224,11 @@ static void efi_disk_add_dev(const char *name,
                goto out_of_memory;
 
        /* Hook up to the device list */
-       INIT_LIST_HEAD(&diskobj->parent.protocols);
-       list_add_tail(&diskobj->parent.link, &efi_obj_list);
+       efi_add_handle(&diskobj->parent);
 
        /* Fill in object data */
        diskobj->dp = efi_dp_from_part(desc, part);
        diskobj->part = part;
-       diskobj->parent.handle = diskobj;
        ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid,
                               &diskobj->ops);
        if (ret != EFI_SUCCESS)
index 498184d754209bfa2df9f73539933520e977a496..3caddd5f8442cf97a96a7301e647a2e6581a8017 100644 (file)
@@ -180,11 +180,9 @@ int efi_gop_register(void)
        }
 
        /* Hook up to the device list */
-       INIT_LIST_HEAD(&gopobj->parent.protocols);
-       list_add_tail(&gopobj->parent.link, &efi_obj_list);
+       efi_add_handle(&gopobj->parent);
 
        /* Fill in object data */
-       gopobj->parent.handle = &gopobj->ops;
        ret = efi_add_protocol(gopobj->parent.handle, &efi_gop_guid,
                               &gopobj->ops);
        if (ret != EFI_SUCCESS) {
index 74a67c5365d937f8b847809d2f76614494b5a640..8c5d5b492cab03df847ea6a443c3919cbe592a5b 100644 (file)
@@ -296,11 +296,9 @@ int efi_net_register(void)
                goto out_of_memory;
 
        /* Hook net up to the device list */
-       INIT_LIST_HEAD(&netobj->parent.protocols);
-       list_add_tail(&netobj->parent.link, &efi_obj_list);
+       efi_add_handle(&netobj->parent);
 
        /* Fill in object data */
-       netobj->parent.handle = &netobj->net;
        r = efi_add_protocol(netobj->parent.handle, &efi_net_guid,
                             &netobj->net);
        if (r != EFI_SUCCESS)