/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * (C) Copyright 2020 Hewlett Packard Enterprise Development LP * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. */ /* * Cross Partition Communication (XPC) partition support. * * This is the part of XPC that detects the presence/absence of * other partitions. It provides a heartbeat and monitors the * heartbeats of other partitions. * */ #include <linux/device.h> #include <linux/hardirq.h> #include <linux/slab.h> #include "xpc.h" #include <asm/uv/uv_hub.h> /* XPC is exiting flag */ int xpc_exiting; /* this partition's reserved page pointers */ struct xpc_rsvd_page *xpc_rsvd_page; static unsigned long *xpc_part_nasids; unsigned long *xpc_mach_nasids; static int xpc_nasid_mask_nbytes; /* #of bytes in nasid mask */ int xpc_nasid_mask_nlongs; /* #of longs in nasid mask */ struct xpc_partition *xpc_partitions; /* * Guarantee that the kmalloc'd memory is cacheline aligned. */ void * xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) { … } /* * Given a nasid, get the physical address of the partition's reserved page * for that nasid. This function returns 0 on any error. */ static unsigned long xpc_get_rsvd_page_pa(int nasid) { … } /* * Fill the partition reserved page with the information needed by * other partitions to discover we are alive and establish initial * communications. */ int xpc_setup_rsvd_page(void) { … } void xpc_teardown_rsvd_page(void) { … } /* * Get a copy of a portion of the remote partition's rsvd page. * * remote_rp points to a buffer that is cacheline aligned for BTE copies and * is large enough to contain a copy of their reserved page header and * part_nasids mask. */ enum xp_retval xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids, struct xpc_rsvd_page *remote_rp, unsigned long *remote_rp_pa) { … } /* * See if the other side has responded to a partition deactivate request * from us. Though we requested the remote partition to deactivate with regard * to us, we really only need to wait for the other side to disengage from us. */ static int __xpc_partition_disengaged(struct xpc_partition *part, bool from_timer) { … } int xpc_partition_disengaged(struct xpc_partition *part) { … } int xpc_partition_disengaged_from_timer(struct xpc_partition *part) { … } /* * Mark specified partition as active. */ enum xp_retval xpc_mark_partition_active(struct xpc_partition *part) { … } /* * Start the process of deactivating the specified partition. */ void xpc_deactivate_partition(const int line, struct xpc_partition *part, enum xp_retval reason) { … } /* * Mark specified partition as inactive. */ void xpc_mark_partition_inactive(struct xpc_partition *part) { … } /* * SAL has provided a partition and machine mask. The partition mask * contains a bit for each even nasid in our partition. The machine * mask contains a bit for each even nasid in the entire machine. * * Using those two bit arrays, we can determine which nasids are * known in the machine. Each should also have a reserved page * initialized if they are available for partitioning. */ void xpc_discovery(void) { … } /* * Given a partid, get the nasids owned by that partition from the * remote partition's reserved page. */ enum xp_retval xpc_initiate_partid_to_nasids(short partid, void *nasid_mask) { … }