#include <linux/memregion.h>
#include <linux/genalloc.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/slab.h>
#include <linux/uuid.h>
#include <linux/sort.h>
#include <linux/idr.h>
#include <linux/memory-tiers.h>
#include <cxlmem.h>
#include <cxl.h>
#include "core.h"
static struct cxl_region *to_cxl_region(struct device *dev);
#define __ACCESS_ATTR_RO(_level, _name) …
#define ACCESS_DEVICE_ATTR_RO(level, name) …
#define ACCESS_ATTR_RO(level, attrib) …
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
#define ACCESS_ATTR_DECLARE(level, attrib) …
static struct attribute *access0_coordinate_attrs[] = …;
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
ACCESS_ATTR_RO(…);
static struct attribute *access1_coordinate_attrs[] = …;
#define ACCESS_VISIBLE(level) …
ACCESS_VISIBLE(0);
ACCESS_VISIBLE(1);
static const struct attribute_group cxl_region_access0_coordinate_group = …;
static const struct attribute_group *get_cxl_region_access0_group(void)
{ … }
static const struct attribute_group cxl_region_access1_coordinate_group = …;
static const struct attribute_group *get_cxl_region_access1_group(void)
{ … }
static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static int is_dup(struct device *match, void *data)
{ … }
static ssize_t uuid_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static DEVICE_ATTR_RW(uuid);
static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port,
struct cxl_region *cxlr)
{ … }
static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
{ … }
static void cxl_region_decode_reset(struct cxl_region *cxlr, int count)
{ … }
static int commit_decoder(struct cxl_decoder *cxld)
{ … }
static int cxl_region_decode_commit(struct cxl_region *cxlr)
{ … }
static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static ssize_t commit_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RW(commit);
static umode_t cxl_region_visible(struct kobject *kobj, struct attribute *a,
int n)
{ … }
static ssize_t interleave_ways_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static const struct attribute_group *get_cxl_region_target_group(void);
static ssize_t interleave_ways_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static DEVICE_ATTR_RW(interleave_ways);
static ssize_t interleave_granularity_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t interleave_granularity_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static DEVICE_ATTR_RW(interleave_granularity);
static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(resource);
static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(mode);
static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
{ … }
static void cxl_region_iomem_release(struct cxl_region *cxlr)
{ … }
static int free_hpa(struct cxl_region *cxlr)
{ … }
static ssize_t size_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static ssize_t size_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RW(size);
static struct attribute *cxl_region_attrs[] = …;
static const struct attribute_group cxl_region_group = …;
static size_t show_targetN(struct cxl_region *cxlr, char *buf, int pos)
{ … }
static int check_commit_order(struct device *dev, const void *data)
{ … }
static int match_free_decoder(struct device *dev, void *data)
{ … }
static int match_auto_decoder(struct device *dev, void *data)
{ … }
static struct cxl_decoder *
cxl_region_find_decoder(struct cxl_port *port,
struct cxl_endpoint_decoder *cxled,
struct cxl_region *cxlr)
{ … }
static bool auto_order_ok(struct cxl_port *port, struct cxl_region *cxlr_iter,
struct cxl_decoder *cxld)
{ … }
static struct cxl_region_ref *
alloc_region_ref(struct cxl_port *port, struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled)
{ … }
static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr)
{ … }
static void free_region_ref(struct cxl_region_ref *cxl_rr)
{ … }
static int cxl_rr_ep_add(struct cxl_region_ref *cxl_rr,
struct cxl_endpoint_decoder *cxled)
{ … }
static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled,
struct cxl_region_ref *cxl_rr)
{ … }
static int cxl_port_attach_region(struct cxl_port *port,
struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled, int pos)
{ … }
static void cxl_port_detach_region(struct cxl_port *port,
struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled)
{ … }
static int check_last_peer(struct cxl_endpoint_decoder *cxled,
struct cxl_ep *ep, struct cxl_region_ref *cxl_rr,
int distance)
{ … }
static int check_interleave_cap(struct cxl_decoder *cxld, int iw, int ig)
{ … }
static int cxl_port_setup_targets(struct cxl_port *port,
struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled)
{ … }
static void cxl_port_reset_targets(struct cxl_port *port,
struct cxl_region *cxlr)
{ … }
static void cxl_region_teardown_targets(struct cxl_region *cxlr)
{ … }
static int cxl_region_setup_targets(struct cxl_region *cxlr)
{ … }
static int cxl_region_validate_position(struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled,
int pos)
{ … }
static int cxl_region_attach_position(struct cxl_region *cxlr,
struct cxl_root_decoder *cxlrd,
struct cxl_endpoint_decoder *cxled,
const struct cxl_dport *dport, int pos)
{ … }
static int cxl_region_attach_auto(struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled, int pos)
{ … }
static int cmp_interleave_pos(const void *a, const void *b)
{ … }
static struct cxl_port *next_port(struct cxl_port *port)
{ … }
static int match_switch_decoder_by_range(struct device *dev, void *data)
{ … }
static int find_pos_and_ways(struct cxl_port *port, struct range *range,
int *pos, int *ways)
{ … }
static int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled)
{ … }
static int cxl_region_sort_targets(struct cxl_region *cxlr)
{ … }
static int cxl_region_attach(struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled, int pos)
{ … }
static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
{ … }
void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
{ … }
static int attach_target(struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled, int pos,
unsigned int state)
{ … }
static int detach_target(struct cxl_region *cxlr, int pos)
{ … }
static size_t store_targetN(struct cxl_region *cxlr, const char *buf, int pos,
size_t len)
{ … }
#define TARGET_ATTR_RW(n) …
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
TARGET_ATTR_RW(…);
static struct attribute *target_attrs[] = …;
static umode_t cxl_region_target_visible(struct kobject *kobj,
struct attribute *a, int n)
{ … }
static const struct attribute_group cxl_region_target_group = …;
static const struct attribute_group *get_cxl_region_target_group(void)
{ … }
static const struct attribute_group *region_groups[] = …;
static void cxl_region_release(struct device *dev)
{ … }
const struct device_type cxl_region_type = …;
bool is_cxl_region(struct device *dev)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static struct cxl_region *to_cxl_region(struct device *dev)
{ … }
static void unregister_region(void *_cxlr)
{ … }
static struct lock_class_key cxl_region_key;
static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int id)
{ … }
static bool cxl_region_update_coordinates(struct cxl_region *cxlr, int nid)
{ … }
static int cxl_region_perf_attrs_callback(struct notifier_block *nb,
unsigned long action, void *arg)
{ … }
static int cxl_region_calculate_adistance(struct notifier_block *nb,
unsigned long nid, void *data)
{ … }
static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
int id,
enum cxl_decoder_mode mode,
enum cxl_decoder_type type)
{ … }
static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
{ … }
static ssize_t create_pmem_region_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static ssize_t create_ram_region_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
enum cxl_decoder_mode mode, int id)
{ … }
static ssize_t create_pmem_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
DEVICE_ATTR_RW(…);
static ssize_t create_ram_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
DEVICE_ATTR_RW(…);
static ssize_t region_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
DEVICE_ATTR_RO(…);
static struct cxl_region *
cxl_find_region_by_name(struct cxl_root_decoder *cxlrd, const char *name)
{ … }
static ssize_t delete_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
DEVICE_ATTR_WO(…);
static void cxl_pmem_region_release(struct device *dev)
{ … }
static const struct attribute_group *cxl_pmem_region_attribute_groups[] = …;
const struct device_type cxl_pmem_region_type = …;
bool is_cxl_pmem_region(struct device *dev)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
struct cxl_poison_context { … };
static int cxl_get_poison_unmapped(struct cxl_memdev *cxlmd,
struct cxl_poison_context *ctx)
{ … }
static int poison_by_decoder(struct device *dev, void *arg)
{ … }
int cxl_get_poison_by_endpoint(struct cxl_port *port)
{ … }
struct cxl_dpa_to_region_context { … };
static int __cxl_dpa_to_region(struct device *dev, void *arg)
{ … }
struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa)
{ … }
static bool cxl_is_hpa_in_chunk(u64 hpa, struct cxl_region *cxlr, int pos)
{ … }
u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
u64 dpa)
{ … }
static struct lock_class_key cxl_pmem_region_key;
static int cxl_pmem_region_alloc(struct cxl_region *cxlr)
{ … }
static void cxl_dax_region_release(struct device *dev)
{ … }
static const struct attribute_group *cxl_dax_region_attribute_groups[] = …;
const struct device_type cxl_dax_region_type = …;
static bool is_cxl_dax_region(struct device *dev)
{ … }
struct cxl_dax_region *to_cxl_dax_region(struct device *dev)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static struct lock_class_key cxl_dax_region_key;
static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr)
{ … }
static void cxlr_pmem_unregister(void *_cxlr_pmem)
{ … }
static void cxlr_release_nvdimm(void *_cxlr)
{ … }
static int devm_cxl_add_pmem_region(struct cxl_region *cxlr)
{ … }
static void cxlr_dax_unregister(void *_cxlr_dax)
{ … }
static int devm_cxl_add_dax_region(struct cxl_region *cxlr)
{ … }
static int match_root_decoder_by_range(struct device *dev, void *data)
{ … }
static int match_region_by_range(struct device *dev, void *data)
{ … }
static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
struct cxl_endpoint_decoder *cxled)
{ … }
int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
{ … }
EXPORT_SYMBOL_NS_GPL(…);
static int is_system_ram(struct resource *res, void *arg)
{ … }
static void shutdown_notifiers(void *_cxlr)
{ … }
static int cxl_region_probe(struct device *dev)
{ … }
static struct cxl_driver cxl_region_driver = …;
int cxl_region_init(void)
{ … }
void cxl_region_exit(void)
{ … }
MODULE_IMPORT_NS(…);
MODULE_IMPORT_NS(…);
MODULE_ALIAS_CXL(…);