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

base.c (2504B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2014 IBM Corp.
      4 */
      5
      6#include <linux/module.h>
      7#include <linux/rcupdate.h>
      8#include <asm/errno.h>
      9#include <misc/cxl-base.h>
     10#include <linux/of_platform.h>
     11#include "cxl.h"
     12
     13/* protected by rcu */
     14static struct cxl_calls *cxl_calls;
     15
     16atomic_t cxl_use_count = ATOMIC_INIT(0);
     17EXPORT_SYMBOL(cxl_use_count);
     18
     19#ifdef CONFIG_CXL_MODULE
     20
     21static inline struct cxl_calls *cxl_calls_get(void)
     22{
     23	struct cxl_calls *calls = NULL;
     24
     25	rcu_read_lock();
     26	calls = rcu_dereference(cxl_calls);
     27	if (calls && !try_module_get(calls->owner))
     28		calls = NULL;
     29	rcu_read_unlock();
     30
     31	return calls;
     32}
     33
     34static inline void cxl_calls_put(struct cxl_calls *calls)
     35{
     36	BUG_ON(calls != cxl_calls);
     37
     38	/* we don't need to rcu this, as we hold a reference to the module */
     39	module_put(cxl_calls->owner);
     40}
     41
     42#else /* !defined CONFIG_CXL_MODULE */
     43
     44static inline struct cxl_calls *cxl_calls_get(void)
     45{
     46	return cxl_calls;
     47}
     48
     49static inline void cxl_calls_put(struct cxl_calls *calls) { }
     50
     51#endif /* CONFIG_CXL_MODULE */
     52
     53/* AFU refcount management */
     54struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
     55{
     56	return (get_device(&afu->dev) == NULL) ? NULL : afu;
     57}
     58EXPORT_SYMBOL_GPL(cxl_afu_get);
     59
     60void cxl_afu_put(struct cxl_afu *afu)
     61{
     62	put_device(&afu->dev);
     63}
     64EXPORT_SYMBOL_GPL(cxl_afu_put);
     65
     66void cxl_slbia(struct mm_struct *mm)
     67{
     68	struct cxl_calls *calls;
     69
     70	calls = cxl_calls_get();
     71	if (!calls)
     72		return;
     73
     74	if (cxl_ctx_in_use())
     75	    calls->cxl_slbia(mm);
     76
     77	cxl_calls_put(calls);
     78}
     79
     80int register_cxl_calls(struct cxl_calls *calls)
     81{
     82	if (cxl_calls)
     83		return -EBUSY;
     84
     85	rcu_assign_pointer(cxl_calls, calls);
     86	return 0;
     87}
     88EXPORT_SYMBOL_GPL(register_cxl_calls);
     89
     90void unregister_cxl_calls(struct cxl_calls *calls)
     91{
     92	BUG_ON(cxl_calls->owner != calls->owner);
     93	RCU_INIT_POINTER(cxl_calls, NULL);
     94	synchronize_rcu();
     95}
     96EXPORT_SYMBOL_GPL(unregister_cxl_calls);
     97
     98int cxl_update_properties(struct device_node *dn,
     99			  struct property *new_prop)
    100{
    101	return of_update_property(dn, new_prop);
    102}
    103EXPORT_SYMBOL_GPL(cxl_update_properties);
    104
    105static int __init cxl_base_init(void)
    106{
    107	struct device_node *np;
    108	struct platform_device *dev;
    109	int count = 0;
    110
    111	/*
    112	 * Scan for compatible devices in guest only
    113	 */
    114	if (cpu_has_feature(CPU_FTR_HVMODE))
    115		return 0;
    116
    117	for_each_compatible_node(np, NULL, "ibm,coherent-platform-facility") {
    118		dev = of_platform_device_create(np, NULL, NULL);
    119		if (dev)
    120			count++;
    121	}
    122	pr_devel("Found %d cxl device(s)\n", count);
    123	return 0;
    124}
    125device_initcall(cxl_base_init);