cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

stratix10-soc.c (12000B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * FPGA Manager Driver for Intel Stratix10 SoC
      4 *
      5 *  Copyright (C) 2018 Intel Corporation
      6 */
      7#include <linux/completion.h>
      8#include <linux/fpga/fpga-mgr.h>
      9#include <linux/firmware/intel/stratix10-svc-client.h>
     10#include <linux/module.h>
     11#include <linux/of.h>
     12#include <linux/of_platform.h>
     13
     14/*
     15 * FPGA programming requires a higher level of privilege (EL3), per the SoC
     16 * design.
     17 */
     18#define NUM_SVC_BUFS	4
     19#define SVC_BUF_SIZE	SZ_512K
     20
     21/* Indicates buffer is in use if set */
     22#define SVC_BUF_LOCK	0
     23
     24#define S10_BUFFER_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_BUFFER_TIMEOUT_MS))
     25#define S10_RECONFIG_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_REQUEST_TIMEOUT_MS))
     26
     27/*
     28 * struct s10_svc_buf
     29 * buf:  virtual address of buf provided by service layer
     30 * lock: locked if buffer is in use
     31 */
     32struct s10_svc_buf {
     33	char *buf;
     34	unsigned long lock;
     35};
     36
     37struct s10_priv {
     38	struct stratix10_svc_chan *chan;
     39	struct stratix10_svc_client client;
     40	struct completion status_return_completion;
     41	struct s10_svc_buf svc_bufs[NUM_SVC_BUFS];
     42	unsigned long status;
     43};
     44
     45static int s10_svc_send_msg(struct s10_priv *priv,
     46			    enum stratix10_svc_command_code command,
     47			    void *payload, u32 payload_length)
     48{
     49	struct stratix10_svc_chan *chan = priv->chan;
     50	struct device *dev = priv->client.dev;
     51	struct stratix10_svc_client_msg msg;
     52	int ret;
     53
     54	dev_dbg(dev, "%s cmd=%d payload=%p length=%d\n",
     55		__func__, command, payload, payload_length);
     56
     57	msg.command = command;
     58	msg.payload = payload;
     59	msg.payload_length = payload_length;
     60
     61	ret = stratix10_svc_send(chan, &msg);
     62	dev_dbg(dev, "stratix10_svc_send returned status %d\n", ret);
     63
     64	return ret;
     65}
     66
     67/*
     68 * Free buffers allocated from the service layer's pool that are not in use.
     69 * Return true when all buffers are freed.
     70 */
     71static bool s10_free_buffers(struct fpga_manager *mgr)
     72{
     73	struct s10_priv *priv = mgr->priv;
     74	uint num_free = 0;
     75	uint i;
     76
     77	for (i = 0; i < NUM_SVC_BUFS; i++) {
     78		if (!priv->svc_bufs[i].buf) {
     79			num_free++;
     80			continue;
     81		}
     82
     83		if (!test_and_set_bit_lock(SVC_BUF_LOCK,
     84					   &priv->svc_bufs[i].lock)) {
     85			stratix10_svc_free_memory(priv->chan,
     86						  priv->svc_bufs[i].buf);
     87			priv->svc_bufs[i].buf = NULL;
     88			num_free++;
     89		}
     90	}
     91
     92	return num_free == NUM_SVC_BUFS;
     93}
     94
     95/*
     96 * Returns count of how many buffers are not in use.
     97 */
     98static uint s10_free_buffer_count(struct fpga_manager *mgr)
     99{
    100	struct s10_priv *priv = mgr->priv;
    101	uint num_free = 0;
    102	uint i;
    103
    104	for (i = 0; i < NUM_SVC_BUFS; i++)
    105		if (!priv->svc_bufs[i].buf)
    106			num_free++;
    107
    108	return num_free;
    109}
    110
    111/*
    112 * s10_unlock_bufs
    113 * Given the returned buffer address, match that address to our buffer struct
    114 * and unlock that buffer.  This marks it as available to be refilled and sent
    115 * (or freed).
    116 * priv: private data
    117 * kaddr: kernel address of buffer that was returned from service layer
    118 */
    119static void s10_unlock_bufs(struct s10_priv *priv, void *kaddr)
    120{
    121	uint i;
    122
    123	if (!kaddr)
    124		return;
    125
    126	for (i = 0; i < NUM_SVC_BUFS; i++)
    127		if (priv->svc_bufs[i].buf == kaddr) {
    128			clear_bit_unlock(SVC_BUF_LOCK,
    129					 &priv->svc_bufs[i].lock);
    130			return;
    131		}
    132
    133	WARN(1, "Unknown buffer returned from service layer %p\n", kaddr);
    134}
    135
    136/*
    137 * s10_receive_callback - callback for service layer to use to provide client
    138 * (this driver) messages received through the mailbox.
    139 * client: service layer client struct
    140 * data: message from service layer
    141 */
    142static void s10_receive_callback(struct stratix10_svc_client *client,
    143				 struct stratix10_svc_cb_data *data)
    144{
    145	struct s10_priv *priv = client->priv;
    146	u32 status;
    147	int i;
    148
    149	WARN_ONCE(!data, "%s: stratix10_svc_rc_data = NULL", __func__);
    150
    151	status = data->status;
    152
    153	/*
    154	 * Here we set status bits as we receive them.  Elsewhere, we always use
    155	 * test_and_clear_bit() to check status in priv->status
    156	 */
    157	for (i = 0; i <= SVC_STATUS_ERROR; i++)
    158		if (status & (1 << i))
    159			set_bit(i, &priv->status);
    160
    161	if (status & BIT(SVC_STATUS_BUFFER_DONE)) {
    162		s10_unlock_bufs(priv, data->kaddr1);
    163		s10_unlock_bufs(priv, data->kaddr2);
    164		s10_unlock_bufs(priv, data->kaddr3);
    165	}
    166
    167	complete(&priv->status_return_completion);
    168}
    169
    170/*
    171 * s10_ops_write_init - prepare for FPGA reconfiguration by requesting
    172 * partial reconfig and allocating buffers from the service layer.
    173 */
    174static int s10_ops_write_init(struct fpga_manager *mgr,
    175			      struct fpga_image_info *info,
    176			      const char *buf, size_t count)
    177{
    178	struct s10_priv *priv = mgr->priv;
    179	struct device *dev = priv->client.dev;
    180	struct stratix10_svc_command_config_type ctype;
    181	char *kbuf;
    182	uint i;
    183	int ret;
    184
    185	ctype.flags = 0;
    186	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
    187		dev_dbg(dev, "Requesting partial reconfiguration.\n");
    188		ctype.flags |= BIT(COMMAND_RECONFIG_FLAG_PARTIAL);
    189	} else {
    190		dev_dbg(dev, "Requesting full reconfiguration.\n");
    191	}
    192
    193	reinit_completion(&priv->status_return_completion);
    194	ret = s10_svc_send_msg(priv, COMMAND_RECONFIG,
    195			       &ctype, sizeof(ctype));
    196	if (ret < 0)
    197		goto init_done;
    198
    199	ret = wait_for_completion_timeout(
    200		&priv->status_return_completion, S10_RECONFIG_TIMEOUT);
    201	if (!ret) {
    202		dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n");
    203		ret = -ETIMEDOUT;
    204		goto init_done;
    205	}
    206
    207	ret = 0;
    208	if (!test_and_clear_bit(SVC_STATUS_OK, &priv->status)) {
    209		ret = -ETIMEDOUT;
    210		goto init_done;
    211	}
    212
    213	/* Allocate buffers from the service layer's pool. */
    214	for (i = 0; i < NUM_SVC_BUFS; i++) {
    215		kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);
    216		if (!kbuf) {
    217			s10_free_buffers(mgr);
    218			ret = -ENOMEM;
    219			goto init_done;
    220		}
    221
    222		priv->svc_bufs[i].buf = kbuf;
    223		priv->svc_bufs[i].lock = 0;
    224	}
    225
    226init_done:
    227	stratix10_svc_done(priv->chan);
    228	return ret;
    229}
    230
    231/*
    232 * s10_send_buf - send a buffer to the service layer queue
    233 * mgr: fpga manager struct
    234 * buf: fpga image buffer
    235 * count: size of buf in bytes
    236 * Returns # of bytes transferred or -ENOBUFS if the all the buffers are in use
    237 * or if the service queue is full. Never returns 0.
    238 */
    239static int s10_send_buf(struct fpga_manager *mgr, const char *buf, size_t count)
    240{
    241	struct s10_priv *priv = mgr->priv;
    242	struct device *dev = priv->client.dev;
    243	void *svc_buf;
    244	size_t xfer_sz;
    245	int ret;
    246	uint i;
    247
    248	/* get/lock a buffer that that's not being used */
    249	for (i = 0; i < NUM_SVC_BUFS; i++)
    250		if (!test_and_set_bit_lock(SVC_BUF_LOCK,
    251					   &priv->svc_bufs[i].lock))
    252			break;
    253
    254	if (i == NUM_SVC_BUFS)
    255		return -ENOBUFS;
    256
    257	xfer_sz = count < SVC_BUF_SIZE ? count : SVC_BUF_SIZE;
    258
    259	svc_buf = priv->svc_bufs[i].buf;
    260	memcpy(svc_buf, buf, xfer_sz);
    261	ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_DATA_SUBMIT,
    262			       svc_buf, xfer_sz);
    263	if (ret < 0) {
    264		dev_err(dev,
    265			"Error while sending data to service layer (%d)", ret);
    266		clear_bit_unlock(SVC_BUF_LOCK, &priv->svc_bufs[i].lock);
    267		return ret;
    268	}
    269
    270	return xfer_sz;
    271}
    272
    273/*
    274 * Send an FPGA image to privileged layers to write to the FPGA.  When done
    275 * sending, free all service layer buffers we allocated in write_init.
    276 */
    277static int s10_ops_write(struct fpga_manager *mgr, const char *buf,
    278			 size_t count)
    279{
    280	struct s10_priv *priv = mgr->priv;
    281	struct device *dev = priv->client.dev;
    282	long wait_status;
    283	int sent = 0;
    284	int ret = 0;
    285
    286	/*
    287	 * Loop waiting for buffers to be returned.  When a buffer is returned,
    288	 * reuse it to send more data or free if if all data has been sent.
    289	 */
    290	while (count > 0 || s10_free_buffer_count(mgr) != NUM_SVC_BUFS) {
    291		reinit_completion(&priv->status_return_completion);
    292
    293		if (count > 0) {
    294			sent = s10_send_buf(mgr, buf, count);
    295			if (sent < 0)
    296				continue;
    297
    298			count -= sent;
    299			buf += sent;
    300		} else {
    301			if (s10_free_buffers(mgr))
    302				return 0;
    303
    304			ret = s10_svc_send_msg(
    305				priv, COMMAND_RECONFIG_DATA_CLAIM,
    306				NULL, 0);
    307			if (ret < 0)
    308				break;
    309		}
    310
    311		/*
    312		 * If callback hasn't already happened, wait for buffers to be
    313		 * returned from service layer
    314		 */
    315		wait_status = 1; /* not timed out */
    316		if (!priv->status)
    317			wait_status = wait_for_completion_timeout(
    318				&priv->status_return_completion,
    319				S10_BUFFER_TIMEOUT);
    320
    321		if (test_and_clear_bit(SVC_STATUS_BUFFER_DONE, &priv->status) ||
    322		    test_and_clear_bit(SVC_STATUS_BUFFER_SUBMITTED,
    323				       &priv->status)) {
    324			ret = 0;
    325			continue;
    326		}
    327
    328		if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
    329			dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
    330			ret = -EFAULT;
    331			break;
    332		}
    333
    334		if (!wait_status) {
    335			dev_err(dev, "timeout waiting for svc layer buffers\n");
    336			ret = -ETIMEDOUT;
    337			break;
    338		}
    339	}
    340
    341	if (!s10_free_buffers(mgr))
    342		dev_err(dev, "%s not all buffers were freed\n", __func__);
    343
    344	return ret;
    345}
    346
    347static int s10_ops_write_complete(struct fpga_manager *mgr,
    348				  struct fpga_image_info *info)
    349{
    350	struct s10_priv *priv = mgr->priv;
    351	struct device *dev = priv->client.dev;
    352	unsigned long timeout;
    353	int ret;
    354
    355	timeout = usecs_to_jiffies(info->config_complete_timeout_us);
    356
    357	do {
    358		reinit_completion(&priv->status_return_completion);
    359
    360		ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_STATUS, NULL, 0);
    361		if (ret < 0)
    362			break;
    363
    364		ret = wait_for_completion_timeout(
    365			&priv->status_return_completion, timeout);
    366		if (!ret) {
    367			dev_err(dev,
    368				"timeout waiting for RECONFIG_COMPLETED\n");
    369			ret = -ETIMEDOUT;
    370			break;
    371		}
    372		/* Not error or timeout, so ret is # of jiffies until timeout */
    373		timeout = ret;
    374		ret = 0;
    375
    376		if (test_and_clear_bit(SVC_STATUS_COMPLETED, &priv->status))
    377			break;
    378
    379		if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
    380			dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
    381			ret = -EFAULT;
    382			break;
    383		}
    384	} while (1);
    385
    386	stratix10_svc_done(priv->chan);
    387
    388	return ret;
    389}
    390
    391static const struct fpga_manager_ops s10_ops = {
    392	.write_init = s10_ops_write_init,
    393	.write = s10_ops_write,
    394	.write_complete = s10_ops_write_complete,
    395};
    396
    397static int s10_probe(struct platform_device *pdev)
    398{
    399	struct device *dev = &pdev->dev;
    400	struct s10_priv *priv;
    401	struct fpga_manager *mgr;
    402	int ret;
    403
    404	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    405	if (!priv)
    406		return -ENOMEM;
    407
    408	priv->client.dev = dev;
    409	priv->client.receive_cb = s10_receive_callback;
    410	priv->client.priv = priv;
    411
    412	priv->chan = stratix10_svc_request_channel_byname(&priv->client,
    413							  SVC_CLIENT_FPGA);
    414	if (IS_ERR(priv->chan)) {
    415		dev_err(dev, "couldn't get service channel (%s)\n",
    416			SVC_CLIENT_FPGA);
    417		return PTR_ERR(priv->chan);
    418	}
    419
    420	init_completion(&priv->status_return_completion);
    421
    422	mgr = fpga_mgr_register(dev, "Stratix10 SOC FPGA Manager",
    423				&s10_ops, priv);
    424	if (IS_ERR(mgr)) {
    425		dev_err(dev, "unable to register FPGA manager\n");
    426		ret = PTR_ERR(mgr);
    427		goto probe_err;
    428	}
    429
    430	platform_set_drvdata(pdev, mgr);
    431	return 0;
    432
    433probe_err:
    434	stratix10_svc_free_channel(priv->chan);
    435	return ret;
    436}
    437
    438static int s10_remove(struct platform_device *pdev)
    439{
    440	struct fpga_manager *mgr = platform_get_drvdata(pdev);
    441	struct s10_priv *priv = mgr->priv;
    442
    443	fpga_mgr_unregister(mgr);
    444	stratix10_svc_free_channel(priv->chan);
    445
    446	return 0;
    447}
    448
    449static const struct of_device_id s10_of_match[] = {
    450	{.compatible = "intel,stratix10-soc-fpga-mgr"},
    451	{.compatible = "intel,agilex-soc-fpga-mgr"},
    452	{},
    453};
    454
    455MODULE_DEVICE_TABLE(of, s10_of_match);
    456
    457static struct platform_driver s10_driver = {
    458	.probe = s10_probe,
    459	.remove = s10_remove,
    460	.driver = {
    461		.name	= "Stratix10 SoC FPGA manager",
    462		.of_match_table = of_match_ptr(s10_of_match),
    463	},
    464};
    465
    466static int __init s10_init(void)
    467{
    468	struct device_node *fw_np;
    469	struct device_node *np;
    470	int ret;
    471
    472	fw_np = of_find_node_by_name(NULL, "svc");
    473	if (!fw_np)
    474		return -ENODEV;
    475
    476	of_node_get(fw_np);
    477	np = of_find_matching_node(fw_np, s10_of_match);
    478	if (!np) {
    479		of_node_put(fw_np);
    480		return -ENODEV;
    481	}
    482
    483	of_node_put(np);
    484	ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL);
    485	of_node_put(fw_np);
    486	if (ret)
    487		return ret;
    488
    489	return platform_driver_register(&s10_driver);
    490}
    491
    492static void __exit s10_exit(void)
    493{
    494	return platform_driver_unregister(&s10_driver);
    495}
    496
    497module_init(s10_init);
    498module_exit(s10_exit);
    499
    500MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
    501MODULE_DESCRIPTION("Intel Stratix 10 SOC FPGA Manager");
    502MODULE_LICENSE("GPL v2");