lkml.org 
[lkml]   [2022]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 12/13] gunyah: rsc_mgr: Add subdevices bus
    Date
    Gunyah Resource Manager exposes an interface which should occupy a few
    devices on Linux:
    - a remote procedure call framework to talk to RM
    - a console device for VMs to interact with each other
    - a virtual machine manager to launch VMs, share memory with them,
    schedule runtime for those VMs, and handle certain faults.

    Create a virtual device bus for the console and VM Manager functions.

    Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
    ---
    drivers/virt/gunyah/Makefile | 2 +-
    drivers/virt/gunyah/rsc_mgr.c | 45 ++++++++++++++++-
    drivers/virt/gunyah/rsc_mgr.h | 10 ++++
    drivers/virt/gunyah/rsc_mgr_bus.c | 84 +++++++++++++++++++++++++++++++
    include/linux/gunyah_rsc_mgr.h | 20 ++++++++
    include/linux/mod_devicetable.h | 8 +++
    scripts/mod/devicetable-offsets.c | 3 ++
    scripts/mod/file2alias.c | 10 ++++
    8 files changed, 180 insertions(+), 2 deletions(-)
    create mode 100644 drivers/virt/gunyah/rsc_mgr_bus.c

    diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
    index 5eb6ad3c45ba..c376f403e712 100644
    --- a/drivers/virt/gunyah/Makefile
    +++ b/drivers/virt/gunyah/Makefile
    @@ -1,5 +1,5 @@
    gunyah-y += gunyah.o
    obj-$(CONFIG_GUNYAH) += gunyah.o

    -gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o
    +gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o rsc_mgr_bus.o
    obj-$(CONFIG_GUNYAH_RESORUCE_MANAGER) += gunyah_rsc_mgr.o
    diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c
    index 0e2f04984ada..cdf96cb29c23 100644
    --- a/drivers/virt/gunyah/rsc_mgr.c
    +++ b/drivers/virt/gunyah/rsc_mgr.c
    @@ -98,6 +98,8 @@ struct gh_rsc_mgr {
    struct mutex send_lock;

    struct work_struct recv_work;
    +
    + struct gh_rm_device console_dev, vm_mgr_dev;
    };

    static struct gh_rsc_mgr *__rsc_mgr;
    @@ -566,13 +568,30 @@ static int gh_rm_drv_probe(struct platform_device *pdev)

    __rsc_mgr = rsc_mgr;

    + ret = gh_rm_device_add(&rsc_mgr->console_dev, &pdev->dev, GH_RM_DEVICE_CONSOLE);
    + if (ret)
    + goto err_msgq;
    +
    + ret = gh_rm_device_add(&rsc_mgr->vm_mgr_dev, &pdev->dev, GH_RM_DEVICE_VM_MGR);
    + if (ret)
    + goto err_console_remove;
    +
    return 0;
    +
    +err_console_remove:
    + gh_rm_device_delete(&rsc_mgr->console_dev);
    +err_msgq:
    + gunyah_msgq_remove(&rsc_mgr->msgq);
    + return ret;
    }

    static int gh_rm_drv_remove(struct platform_device *pdev)
    {
    struct gh_rsc_mgr *rsc_mgr = platform_get_drvdata(pdev);

    + gh_rm_device_delete(&rsc_mgr->vm_mgr_dev);
    + gh_rm_device_delete(&rsc_mgr->console_dev);
    +
    __rsc_mgr = NULL;

    mbox_free_channel(gunyah_msgq_chan(&rsc_mgr->msgq));
    @@ -595,7 +614,31 @@ static struct platform_driver gh_rm_driver = {
    .of_match_table = gh_rm_of_match,
    },
    };
    -module_platform_driver(gh_rsc_mgr_driver);
    +
    +static int __init gh_rm_init(void)
    +{
    + int ret;
    +
    + ret = gh_rm_bus_register();
    + if (ret) {
    + pr_err("Failed to register gh_rm_bus: %d\n", ret);
    + return ret;
    + }
    +
    + ret = platform_driver_register(&gh_rm_driver);
    + if (ret)
    + gh_rm_bus_unregister();
    +
    + return ret;
    +}
    +subsys_initcall(gh_rm_init);
    +
    +static void __exit gh_rm_exit(void)
    +{
    + platform_driver_unregister(&gh_rm_driver);
    + gh_rm_bus_unregister();
    +}
    +module_exit(gh_rm_exit);

    MODULE_LICENSE("GPL");
    MODULE_DESCRIPTION("Gunyah Resource Manager Driver");
    diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
    index 4620ac648bcf..a511858a456d 100644
    --- a/drivers/virt/gunyah/rsc_mgr.h
    +++ b/drivers/virt/gunyah/rsc_mgr.h
    @@ -53,4 +53,14 @@ struct gh_vm_console_write_req {
    int gh_rm_call(u32 message_id, void *req_buff, size_t req_buff_size,
    void **resp_buf, size_t *resp_buff_size);

    +struct gh_rm_device {
    + struct device dev;
    + const char *name;
    +};
    +
    +int gh_rm_bus_register(void);
    +void gh_rm_bus_unregister(void);
    +int gh_rm_device_add(struct gh_rm_device *ghrm_dev, struct device *parent, const char *name);
    +void gh_rm_device_delete(struct gh_rm_device *ghrm_dev);
    +
    #endif
    diff --git a/drivers/virt/gunyah/rsc_mgr_bus.c b/drivers/virt/gunyah/rsc_mgr_bus.c
    new file mode 100644
    index 000000000000..dfd466c775f4
    --- /dev/null
    +++ b/drivers/virt/gunyah/rsc_mgr_bus.c
    @@ -0,0 +1,84 @@
    +// SPDX-License-Identifier: GPL-2.0-only
    +/*
    + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
    + */
    +
    +#define pr_fmt(fmt) "gh_rsc_mgr: " fmt
    +
    +#include <linux/device.h>
    +#include <linux/gunyah_rsc_mgr.h>
    +#include <linux/mod_devicetable.h>
    +
    +#include "rsc_mgr.h"
    +
    +#define to_gh_rm_device(dev) container_of(dev, struct gh_rm_device, dev)
    +#define to_gh_rm_driver(drv) container_of(drv, struct gh_rm_driver, drv)
    +
    +static int gh_rm_bus_match(struct device *dev, struct device_driver *drv)
    +{
    + struct gh_rm_device *ghrm_dev = to_gh_rm_device(dev);
    + struct gh_rm_driver *ghrm_drv = to_gh_rm_driver(drv);
    +
    + // Multiple id_table entries not needed
    + return !strncmp(ghrm_dev->name, ghrm_drv->id_table->name, GUNYAH_RSC_MGR_NAME_SIZE);
    +}
    +
    +static int gh_rm_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
    +{
    + struct gh_rm_device *ghrm_dev = to_gh_rm_device(dev);
    +
    + return add_uevent_var(env, "MODALIAS=%s%s", GUNYAH_RSC_MGR_PREFIX, ghrm_dev->name);
    +}
    +
    +static struct bus_type gh_rm_bus = {
    + .name = "gh_rsc_mgr",
    + .match = gh_rm_bus_match,
    + .uevent = gh_rm_bus_uevent,
    +};
    +
    +int gh_rm_bus_register(void)
    +{
    + return bus_register(&gh_rm_bus);
    +}
    +
    +void gh_rm_bus_unregister(void)
    +{
    + bus_unregister(&gh_rm_bus);
    +}
    +
    +int gh_rm_device_add(struct gh_rm_device *ghrm_dev, struct device *parent, const char *name)
    +{
    + ghrm_dev->dev.bus = &gh_rm_bus;
    + ghrm_dev->dev.parent = parent;
    + ghrm_dev->name = name;
    +
    + device_initialize(&ghrm_dev->dev);
    +
    + dev_set_name(&ghrm_dev->dev, "%s.%s", dev_name(parent), name);
    + return device_add(&ghrm_dev->dev);
    +}
    +
    +void gh_rm_device_delete(struct gh_rm_device *ghrm_dev)
    +{
    + device_del(&ghrm_dev->dev);
    +}
    +
    +int __gh_rm_driver_register(struct gh_rm_driver *ghrm_drv, struct module *owner,
    + const char *modname)
    +{
    + if (WARN_ON(!ghrm_drv->drv.probe) || WARN_ON(!ghrm_drv->id_table))
    + return -EINVAL;
    +
    + ghrm_drv->drv.bus = &gh_rm_bus;
    + ghrm_drv->drv.owner = owner;
    + ghrm_drv->drv.mod_name = modname;
    +
    + return driver_register(&ghrm_drv->drv);
    +}
    +EXPORT_SYMBOL_GPL(__gh_rm_driver_register);
    +
    +void gh_rm_driver_unregister(struct gh_rm_driver *ghrm_drv)
    +{
    + driver_unregister(&ghrm_drv->drv);
    +}
    +EXPORT_SYMBOL_GPL(gh_rm_driver_unregister);
    diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h
    index 2a1a51299247..7aea3344d655 100644
    --- a/include/linux/gunyah_rsc_mgr.h
    +++ b/include/linux/gunyah_rsc_mgr.h
    @@ -9,6 +9,8 @@
    #include <linux/list.h>
    #include <linux/notifier.h>
    #include <linux/gunyah.h>
    +#include <linux/device.h>
    +#include <linux/mod_devicetable.h>

    #define GH_VMID_INVAL U16_MAX

    @@ -41,4 +43,22 @@ int gh_rm_console_close(u16 vmid);
    int gh_rm_console_write(u16 vmid, const char *buf, size_t size);
    int gh_rm_console_flush(u16 vmid);

    +#define GH_RM_DEVICE_CONSOLE "console"
    +#define GH_RM_DEVICE_VM_MGR "vm_mgr"
    +
    +struct gh_rm_driver {
    + const struct gunyah_rsc_mgr_device_id *id_table;
    + struct device_driver drv;
    +};
    +
    +int __gh_rm_driver_register(struct gh_rm_driver *ghrm_drv, struct module *owner,
    + const char *modname);
    +#define gh_rm_driver_register(ghrm_drv) \
    + __gh_rm_driver_register(ghrm_drv, THIS_MODULE, KBUILD_MODNAME)
    +
    +void gh_rm_driver_unregister(struct gh_rm_driver *ghrm_drv);
    +
    +#define module_gh_rm_driver(ghrm_drv) \
    + module_driver(ghrm_drv, gh_rm_driver_register, gh_rm_driver_unregister)
    +
    #endif
    diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
    index 549590e9c644..c4dc0ee6ae00 100644
    --- a/include/linux/mod_devicetable.h
    +++ b/include/linux/mod_devicetable.h
    @@ -911,4 +911,12 @@ struct ishtp_device_id {
    kernel_ulong_t driver_data;
    };

    +#define GUNYAH_RSC_MGR_NAME_SIZE 32
    +#define GUNYAH_RSC_MGR_PREFIX "gh_rsc_mgr:"
    +
    +struct gunyah_rsc_mgr_device_id {
    + const char name[GUNYAH_RSC_MGR_NAME_SIZE];
    + kernel_ulong_t driver_data;
    +};
    +
    #endif /* LINUX_MOD_DEVICETABLE_H */
    diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
    index c0d3bcb99138..7b6944ed9336 100644
    --- a/scripts/mod/devicetable-offsets.c
    +++ b/scripts/mod/devicetable-offsets.c
    @@ -262,5 +262,8 @@ int main(void)
    DEVID(ishtp_device_id);
    DEVID_FIELD(ishtp_device_id, guid);

    + DEVID(gunyah_rsc_mgr_device_id);
    + DEVID_FIELD(gunyah_rsc_mgr_device_id, name);
    +
    return 0;
    }
    diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
    index 80d973144fde..a02b9e8e02a8 100644
    --- a/scripts/mod/file2alias.c
    +++ b/scripts/mod/file2alias.c
    @@ -1452,6 +1452,15 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias)
    return 1;
    }

    +/* Looks like: gh_rsc_mgr:S */
    +static int do_gunyah_rsc_mgr_entry(const char *filename, void *symval, char *alias)
    +{
    + DEF_FIELD_ADDR(symval, gunyah_rsc_mgr_device_id, name);
    + sprintf(alias, GUNYAH_RSC_MGR_PREFIX "%s", *name);
    +
    + return 1;
    +}
    +
    /* Does namelen bytes of name exactly match the symbol? */
    static bool sym_is(const char *name, unsigned namelen, const char *symbol)
    {
    @@ -1531,6 +1540,7 @@ static const struct devtable devtable[] = {
    {"ssam", SIZE_ssam_device_id, do_ssam_entry},
    {"dfl", SIZE_dfl_device_id, do_dfl_entry},
    {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry},
    + {"gh_rsc_mgr", SIZE_gunyah_rsc_mgr_device_id, do_gunyah_rsc_mgr_entry},
    };

    /* Create MODULE_ALIAS() statements.
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-10-11 02:12    [W:2.422 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site