lkml.org 
[lkml]   [2023]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 8/8] crypto: ccp - Allow platform device to be psp master device
    Date
    Move the getters/setters to sp-dev.c, so that they can be accessed from
    sp-pci.c and sp-platform.c. This makes it possible for the psp
    platform_device to set the function pointers and be assigned the role of
    master device by psp_dev_init().

    While the case of a system having both a PCI and ACPI PSP is not
    supported (and not known to occur in the wild), it makes sense to have a
    single static global to assign to. Should such a system occur, the logic
    in psp_set_master() is that the pci device is preferred.

    Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
    Signed-off-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
    ---
    drivers/crypto/ccp/sp-dev.c | 58 ++++++++++++++++++++++++++++++++
    drivers/crypto/ccp/sp-dev.h | 4 +++
    drivers/crypto/ccp/sp-pci.c | 48 --------------------------
    drivers/crypto/ccp/sp-platform.c | 6 ++++
    4 files changed, 68 insertions(+), 48 deletions(-)

    diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c
    index 4c9f442b8a11..0ac1d0eba8bb 100644
    --- a/drivers/crypto/ccp/sp-dev.c
    +++ b/drivers/crypto/ccp/sp-dev.c
    @@ -14,6 +14,8 @@
    #include <linux/kthread.h>
    #include <linux/sched.h>
    #include <linux/interrupt.h>
    +#include <linux/pci.h>
    +#include <linux/platform_device.h>
    #include <linux/spinlock.h>
    #include <linux/spinlock_types.h>
    #include <linux/types.h>
    @@ -39,6 +41,8 @@ static LIST_HEAD(sp_units);
    /* Ever-increasing value to produce unique unit numbers */
    static atomic_t sp_ordinal;

    +static struct sp_device *sp_dev_master;
    +
    static void sp_add_device(struct sp_device *sp)
    {
    unsigned long flags;
    @@ -250,6 +254,60 @@ struct sp_device *sp_get_psp_master_device(void)
    return ret;
    }

    +static bool sp_pci_is_master(struct sp_device *sp)
    +{
    + struct device *dev_cur, *dev_new;
    + struct pci_dev *pdev_cur, *pdev_new;
    +
    + dev_new = sp->dev;
    + dev_cur = sp_dev_master->dev;
    +
    + pdev_new = to_pci_dev(dev_new);
    + pdev_cur = to_pci_dev(dev_cur);
    +
    + if (pdev_new->bus->number < pdev_cur->bus->number)
    + return true;
    +
    + if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn))
    + return true;
    +
    + if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn))
    + return true;
    +
    + return false;
    +}
    +
    +void psp_set_master(struct sp_device *sp)
    +{
    + struct device *dev_cur, *dev_new;
    +
    + if (!sp_dev_master) {
    + sp_dev_master = sp;
    + return;
    + }
    +
    + dev_new = sp->dev;
    + dev_cur = sp_dev_master->dev;
    +
    + if (dev_is_pci(dev_new) && dev_is_pci(dev_cur) && sp_pci_is_master(sp))
    + sp_dev_master = sp;
    + if (dev_is_pci(dev_new) && dev_is_platform(dev_cur))
    + sp_dev_master = sp;
    +}
    +
    +struct sp_device *psp_get_master(void)
    +{
    + return sp_dev_master;
    +}
    +
    +void psp_clear_master(struct sp_device *sp)
    +{
    + if (sp == sp_dev_master) {
    + sp_dev_master = NULL;
    + dev_dbg(sp->dev, "Cleared sp_dev_master\n");
    + }
    +}
    +
    static int __init sp_mod_init(void)
    {
    #ifdef CONFIG_X86
    diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h
    index 20377e67f65d..c05f1fa82ff4 100644
    --- a/drivers/crypto/ccp/sp-dev.h
    +++ b/drivers/crypto/ccp/sp-dev.h
    @@ -129,6 +129,10 @@ int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler,
    void sp_free_psp_irq(struct sp_device *sp, void *data);
    struct sp_device *sp_get_psp_master_device(void);

    +void psp_set_master(struct sp_device *sp);
    +struct sp_device *psp_get_master(void);
    +void psp_clear_master(struct sp_device *sp);
    +
    #ifdef CONFIG_CRYPTO_DEV_SP_CCP

    int ccp_dev_init(struct sp_device *sp);
    diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
    index 084d052fddcc..af8f0f65c4b5 100644
    --- a/drivers/crypto/ccp/sp-pci.c
    +++ b/drivers/crypto/ccp/sp-pci.c
    @@ -30,7 +30,6 @@ struct sp_pci {
    int msix_count;
    struct msix_entry msix_entry[MSIX_VECTORS];
    };
    -static struct sp_device *sp_dev_master;

    #define attribute_show(name, def) \
    static ssize_t name##_show(struct device *d, struct device_attribute *attr, \
    @@ -168,53 +167,6 @@ static void sp_free_irqs(struct sp_device *sp)
    sp->psp_irq = 0;
    }

    -static bool sp_pci_is_master(struct sp_device *sp)
    -{
    - struct device *dev_cur, *dev_new;
    - struct pci_dev *pdev_cur, *pdev_new;
    -
    - dev_new = sp->dev;
    - dev_cur = sp_dev_master->dev;
    -
    - pdev_new = to_pci_dev(dev_new);
    - pdev_cur = to_pci_dev(dev_cur);
    -
    - if (pdev_new->bus->number < pdev_cur->bus->number)
    - return true;
    -
    - if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn))
    - return true;
    -
    - if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn))
    - return true;
    -
    - return false;
    -}
    -
    -static void psp_set_master(struct sp_device *sp)
    -{
    - if (!sp_dev_master) {
    - sp_dev_master = sp;
    - return;
    - }
    -
    - if (sp_pci_is_master(sp))
    - sp_dev_master = sp;
    -}
    -
    -static struct sp_device *psp_get_master(void)
    -{
    - return sp_dev_master;
    -}
    -
    -static void psp_clear_master(struct sp_device *sp)
    -{
    - if (sp == sp_dev_master) {
    - sp_dev_master = NULL;
    - dev_dbg(sp->dev, "Cleared sp_dev_master\n");
    - }
    -}
    -
    static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
    {
    struct sp_device *sp;
    diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c
    index be8306c47196..e22d9fee0956 100644
    --- a/drivers/crypto/ccp/sp-platform.c
    +++ b/drivers/crypto/ccp/sp-platform.c
    @@ -234,6 +234,12 @@ static int sp_platform_probe(struct platform_device *pdev)

    dev_set_drvdata(dev, sp);

    + if (sp_platform->is_platform_device) {
    + sp->set_psp_master_device = psp_set_master;
    + sp->get_psp_master_device = psp_get_master;
    + sp->clear_psp_master_device = psp_clear_master;
    + }
    +
    ret = sp_init(sp);
    if (ret)
    goto e_err;
    --
    2.34.1
    \
     
     \ /
      Last update: 2023-03-27 01:09    [W:4.864 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site