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

pseries-rng.c (2205B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2010 Michael Neuling IBM Corporation
      4 *
      5 * Driver for the pseries hardware RNG for POWER7+ and above
      6 */
      7
      8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/hw_random.h>
     13#include <asm/vio.h>
     14
     15
     16static int pseries_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
     17{
     18	u64 buffer[PLPAR_HCALL_BUFSIZE];
     19	int rc;
     20
     21	rc = plpar_hcall(H_RANDOM, (unsigned long *)buffer);
     22	if (rc != H_SUCCESS) {
     23		pr_err_ratelimited("H_RANDOM call failed %d\n", rc);
     24		return -EIO;
     25	}
     26	memcpy(data, buffer, 8);
     27
     28	/* The hypervisor interface returns 64 bits */
     29	return 8;
     30}
     31
     32/*
     33 * pseries_rng_get_desired_dma - Return desired DMA allocate for CMO operations
     34 *
     35 * This is a required function for a driver to operate in a CMO environment
     36 * but this device does not make use of DMA allocations, return 0.
     37 *
     38 * Return value:
     39 *	Number of bytes of IO data the driver will need to perform well -> 0
     40 */
     41static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
     42{
     43	return 0;
     44};
     45
     46static struct hwrng pseries_rng = {
     47	.name		= KBUILD_MODNAME,
     48	.read		= pseries_rng_read,
     49};
     50
     51static int pseries_rng_probe(struct vio_dev *dev,
     52		const struct vio_device_id *id)
     53{
     54	return hwrng_register(&pseries_rng);
     55}
     56
     57static void pseries_rng_remove(struct vio_dev *dev)
     58{
     59	hwrng_unregister(&pseries_rng);
     60}
     61
     62static const struct vio_device_id pseries_rng_driver_ids[] = {
     63	{ "ibm,random-v1", "ibm,random"},
     64	{ "", "" }
     65};
     66MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids);
     67
     68static struct vio_driver pseries_rng_driver = {
     69	.name = KBUILD_MODNAME,
     70	.probe = pseries_rng_probe,
     71	.remove = pseries_rng_remove,
     72	.get_desired_dma = pseries_rng_get_desired_dma,
     73	.id_table = pseries_rng_driver_ids
     74};
     75
     76static int __init rng_init(void)
     77{
     78	pr_info("Registering IBM pSeries RNG driver\n");
     79	return vio_register_driver(&pseries_rng_driver);
     80}
     81
     82module_init(rng_init);
     83
     84static void __exit rng_exit(void)
     85{
     86	vio_unregister_driver(&pseries_rng_driver);
     87}
     88module_exit(rng_exit);
     89
     90MODULE_LICENSE("GPL");
     91MODULE_AUTHOR("Michael Neuling <mikey@neuling.org>");
     92MODULE_DESCRIPTION("H/W RNG driver for IBM pSeries processors");