194bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson/* 294bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * This file is subject to the terms and conditions of the GNU General Public 394bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * License. See the file "COPYING" in the main directory of this archive 494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * for more details. 594bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * 6361916a943cd9dbda1c0b00879d0225cc919d868Dean Nelson * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. 794bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson */ 894bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 994bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson/* 1094bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * Cross Partition Communication (XPC) uv-based functions. 1194bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * 1294bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * Architecture specific implementation of common functions. 1394bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson * 1494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson */ 1594bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 1694bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson#include <linux/kernel.h> 175b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#include <linux/mm.h> 185b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#include <linux/interrupt.h> 195b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#include <linux/delay.h> 205b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#include <linux/device.h> 212525789b4694d78df4f001063f042b2b74227d26Dean Nelson#include <linux/err.h> 225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 23261f3b4979db88d29fc86aad9f76fbc0c2c6d21aDean Nelson#include <asm/uv/uv_hub.h> 242525789b4694d78df4f001063f042b2b74227d26Dean Nelson#if defined CONFIG_X86_64 252525789b4694d78df4f001063f042b2b74227d26Dean Nelson#include <asm/uv/bios.h> 262525789b4694d78df4f001063f042b2b74227d26Dean Nelson#include <asm/uv/uv_irq.h> 272525789b4694d78df4f001063f042b2b74227d26Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 282525789b4694d78df4f001063f042b2b74227d26Dean Nelson#include <asm/sn/intr.h> 292525789b4694d78df4f001063f042b2b74227d26Dean Nelson#include <asm/sn/sn_sal.h> 302525789b4694d78df4f001063f042b2b74227d26Dean Nelson#endif 315b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#include "../sgi-gru/gru.h" 32261f3b4979db88d29fc86aad9f76fbc0c2c6d21aDean Nelson#include "../sgi-gru/grukservices.h" 3394bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson#include "xpc.h" 3494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 356f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 366f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerstruct uv_IO_APIC_route_entry { 376f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner __u64 vector : 8, 386f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner delivery_mode : 3, 396f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner dest_mode : 1, 406f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner delivery_status : 1, 416f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner polarity : 1, 426f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner __reserved_1 : 1, 436f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner trigger : 1, 446f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mask : 1, 456f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner __reserved_2 : 15, 466f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner dest : 32; 476f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner}; 486f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner#endif 496f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 50a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtstatic struct xpc_heartbeat_uv *xpc_heartbeat_uv; 5133ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 525b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson#define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) 532525789b4694d78df4f001063f042b2b74227d26Dean Nelson#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ 542525789b4694d78df4f001063f042b2b74227d26Dean Nelson XPC_ACTIVATE_MSG_SIZE_UV) 552525789b4694d78df4f001063f042b2b74227d26Dean Nelson#define XPC_ACTIVATE_IRQ_NAME "xpc_activate" 565b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 572525789b4694d78df4f001063f042b2b74227d26Dean Nelson#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES) 582525789b4694d78df4f001063f042b2b74227d26Dean Nelson#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ 592525789b4694d78df4f001063f042b2b74227d26Dean Nelson XPC_NOTIFY_MSG_SIZE_UV) 602525789b4694d78df4f001063f042b2b74227d26Dean Nelson#define XPC_NOTIFY_IRQ_NAME "xpc_notify" 615b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 622525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic struct xpc_gru_mq_uv *xpc_activate_mq_uv; 632525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic struct xpc_gru_mq_uv *xpc_notify_mq_uv; 645b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 655b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic int 66a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtxpc_setup_partitions_uv(void) 675b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson short partid; 695b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition_uv *part_uv; 705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 725b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part_uv = &xpc_partitions[partid].sn.uv; 735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 746f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex); 755b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_init(&part_uv->flags_lock); 765b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part_uv->remote_act_state = XPC_P_AS_INACTIVE; 775b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return 0; 795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 805b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 816f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerstatic void 82a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtxpc_teardown_partitions_uv(void) 836f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner{ 846f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner short partid; 856f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct xpc_partition_uv *part_uv; 866f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner unsigned long irq_flags; 876f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 886f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 896f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv = &xpc_partitions[partid].sn.uv; 906f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 916f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (part_uv->cached_activate_gru_mq_desc != NULL) { 926f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); 936f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 946f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 956f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 966f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner kfree(part_uv->cached_activate_gru_mq_desc); 976f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->cached_activate_gru_mq_desc = NULL; 986f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mutex_unlock(&part_uv-> 996f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner cached_activate_gru_mq_desc_mutex); 1006f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 1016f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 1026f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner} 1036f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 1042525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic int 1052525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) 1062525789b4694d78df4f001063f042b2b74227d26Dean Nelson{ 1076f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 1086f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 1092525789b4694d78df4f001063f042b2b74227d26Dean Nelson#if defined CONFIG_X86_64 1106c2c502910247d2820cb630e7b28fb6bdecdbf45Dimitri Sivanich mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, 1116c2c502910247d2820cb630e7b28fb6bdecdbf45Dimitri Sivanich UV_AFFINITY_CPU); 1122525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (mq->irq < 0) { 1132525789b4694d78df4f001063f042b2b74227d26Dean Nelson dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", 1146f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner -mq->irq); 1156f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner return mq->irq; 1162525789b4694d78df4f001063f042b2b74227d26Dean Nelson } 1172525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1186f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); 1192525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1206f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 1212525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0) 1222525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->irq = SGI_XPC_ACTIVATE; 1232525789b4694d78df4f001063f042b2b74227d26Dean Nelson else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0) 1242525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->irq = SGI_XPC_NOTIFY; 1252525789b4694d78df4f001063f042b2b74227d26Dean Nelson else 1262525789b4694d78df4f001063f042b2b74227d26Dean Nelson return -EINVAL; 1272525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1286f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq; 1296f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value); 1302525789b4694d78df4f001063f042b2b74227d26Dean Nelson#else 1312525789b4694d78df4f001063f042b2b74227d26Dean Nelson #error not a supported configuration 1322525789b4694d78df4f001063f042b2b74227d26Dean Nelson#endif 1332525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1342525789b4694d78df4f001063f042b2b74227d26Dean Nelson return 0; 1352525789b4694d78df4f001063f042b2b74227d26Dean Nelson} 1362525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1372525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic void 1382525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq) 1392525789b4694d78df4f001063f042b2b74227d26Dean Nelson{ 1402525789b4694d78df4f001063f042b2b74227d26Dean Nelson#if defined CONFIG_X86_64 1416c2c502910247d2820cb630e7b28fb6bdecdbf45Dimitri Sivanich uv_teardown_irq(mq->irq); 1422525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1432525789b4694d78df4f001063f042b2b74227d26Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 1442525789b4694d78df4f001063f042b2b74227d26Dean Nelson int mmr_pnode; 1452525789b4694d78df4f001063f042b2b74227d26Dean Nelson unsigned long mmr_value; 1462525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1472525789b4694d78df4f001063f042b2b74227d26Dean Nelson mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 1482525789b4694d78df4f001063f042b2b74227d26Dean Nelson mmr_value = 1UL << 16; 1492525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1502525789b4694d78df4f001063f042b2b74227d26Dean Nelson uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value); 1512525789b4694d78df4f001063f042b2b74227d26Dean Nelson#else 1522525789b4694d78df4f001063f042b2b74227d26Dean Nelson #error not a supported configuration 1532525789b4694d78df4f001063f042b2b74227d26Dean Nelson#endif 1542525789b4694d78df4f001063f042b2b74227d26Dean Nelson} 1552525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1562525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic int 1572525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq) 1582525789b4694d78df4f001063f042b2b74227d26Dean Nelson{ 1592525789b4694d78df4f001063f042b2b74227d26Dean Nelson int ret; 1602525789b4694d78df4f001063f042b2b74227d26Dean Nelson 161c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 162c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 163c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 164c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address), 165c8182f0016fb65a721c4fbe487909a2d56178135Russ Anderson mq->order, &mq->mmr_offset); 1662525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (ret < 0) { 1672525789b4694d78df4f001063f042b2b74227d26Dean Nelson dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n", 1682525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret); 1692525789b4694d78df4f001063f042b2b74227d26Dean Nelson return -EBUSY; 1702525789b4694d78df4f001063f042b2b74227d26Dean Nelson } 171c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt#elif defined CONFIG_X86_64 172c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address), 173c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt mq->order, &mq->mmr_offset); 174c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt if (ret < 0) { 175c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, " 176c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt "ret=%d\n", ret); 177c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt return ret; 178c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt } 1792525789b4694d78df4f001063f042b2b74227d26Dean Nelson#else 1802525789b4694d78df4f001063f042b2b74227d26Dean Nelson #error not a supported configuration 1812525789b4694d78df4f001063f042b2b74227d26Dean Nelson#endif 1822525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1832525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->watchlist_num = ret; 1842525789b4694d78df4f001063f042b2b74227d26Dean Nelson return 0; 1852525789b4694d78df4f001063f042b2b74227d26Dean Nelson} 1862525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1872525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic void 1882525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq) 1892525789b4694d78df4f001063f042b2b74227d26Dean Nelson{ 1902525789b4694d78df4f001063f042b2b74227d26Dean Nelson int ret; 191c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 1922525789b4694d78df4f001063f042b2b74227d26Dean Nelson 1932525789b4694d78df4f001063f042b2b74227d26Dean Nelson#if defined CONFIG_X86_64 194c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num); 1952525789b4694d78df4f001063f042b2b74227d26Dean Nelson BUG_ON(ret != BIOS_STATUS_SUCCESS); 1962525789b4694d78df4f001063f042b2b74227d26Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 197c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num); 1982525789b4694d78df4f001063f042b2b74227d26Dean Nelson BUG_ON(ret != SALRET_OK); 1992525789b4694d78df4f001063f042b2b74227d26Dean Nelson#else 2002525789b4694d78df4f001063f042b2b74227d26Dean Nelson #error not a supported configuration 2012525789b4694d78df4f001063f042b2b74227d26Dean Nelson#endif 2022525789b4694d78df4f001063f042b2b74227d26Dean Nelson} 2032525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2042525789b4694d78df4f001063f042b2b74227d26Dean Nelsonstatic struct xpc_gru_mq_uv * 2052525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, 2065b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson irq_handler_t irq_handler) 2075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 2082525789b4694d78df4f001063f042b2b74227d26Dean Nelson enum xp_retval xp_ret; 2095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson int ret; 2105b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson int nid; 21157e6d258b1e41cd7ceb26fa43ce116939d8440b1Robin Holt int nasid; 2122525789b4694d78df4f001063f042b2b74227d26Dean Nelson int pg_order; 2135b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct page *page; 2142525789b4694d78df4f001063f042b2b74227d26Dean Nelson struct xpc_gru_mq_uv *mq; 2156f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct uv_IO_APIC_route_entry *mmr_value; 2162525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2172525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL); 2182525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (mq == NULL) { 2192525789b4694d78df4f001063f042b2b74227d26Dean Nelson dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " 2202525789b4694d78df4f001063f042b2b74227d26Dean Nelson "a xpc_gru_mq_uv structure\n"); 2212525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = -ENOMEM; 2226f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner goto out_0; 2236f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 2246f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 2256f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc), 2266f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner GFP_KERNEL); 2276f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (mq->gru_mq_desc == NULL) { 2286f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " 2296f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner "a gru_message_queue_desc structure\n"); 2306f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = -ENOMEM; 2312525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_1; 2322525789b4694d78df4f001063f042b2b74227d26Dean Nelson } 2335b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 2342525789b4694d78df4f001063f042b2b74227d26Dean Nelson pg_order = get_order(mq_size); 2352525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->order = pg_order + PAGE_SHIFT; 2362525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq_size = 1UL << mq->order; 2372525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2382525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->mmr_blade = uv_cpu_to_blade_id(cpu); 2392525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2402525789b4694d78df4f001063f042b2b74227d26Dean Nelson nid = cpu_to_node(cpu); 2416484eb3e2a81807722c5f28efef94d8338b7b996Mel Gorman page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, 2422525789b4694d78df4f001063f042b2b74227d26Dean Nelson pg_order); 243bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (page == NULL) { 244bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " 245bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); 2462525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = -ENOMEM; 2472525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_2; 248bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 2492525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq->address = page_address(page); 2505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 2512525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* enable generation of irq when GRU mq operation occurs to this mq */ 2522525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = xpc_gru_mq_watchlist_alloc_uv(mq); 2532525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (ret != 0) 2542525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_3; 2555b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 2562525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name); 2572525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (ret != 0) 2582525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_4; 2592525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2602525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL); 2615b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (ret != 0) { 2625b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n", 2636f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mq->irq, -ret); 2642525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_5; 2655b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 2665b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 26757e6d258b1e41cd7ceb26fa43ce116939d8440b1Robin Holt nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu)); 26857e6d258b1e41cd7ceb26fa43ce116939d8440b1Robin Holt 2696f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value; 2706f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size, 27157e6d258b1e41cd7ceb26fa43ce116939d8440b1Robin Holt nasid, mmr_value->vector, mmr_value->dest); 2726f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (ret != 0) { 2736f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner dev_err(xpc_part, "gru_create_message_queue() returned " 2746f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner "error=%d\n", ret); 2756f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = -EINVAL; 2766f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner goto out_6; 2776f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 2786f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 2792525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* allow other partitions to access this GRU mq */ 2802525789b4694d78df4f001063f042b2b74227d26Dean Nelson xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size); 2812525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (xp_ret != xpSuccess) { 2822525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = -EACCES; 2832525789b4694d78df4f001063f042b2b74227d26Dean Nelson goto out_6; 2842525789b4694d78df4f001063f042b2b74227d26Dean Nelson } 2855b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 2865b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return mq; 2872525789b4694d78df4f001063f042b2b74227d26Dean Nelson 2882525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* something went wrong */ 2892525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_6: 2902525789b4694d78df4f001063f042b2b74227d26Dean Nelson free_irq(mq->irq, NULL); 2912525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_5: 2922525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_release_gru_mq_irq_uv(mq); 2932525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_4: 2942525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_gru_mq_watchlist_free_uv(mq); 2952525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_3: 2962525789b4694d78df4f001063f042b2b74227d26Dean Nelson free_pages((unsigned long)mq->address, pg_order); 2972525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_2: 2986f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner kfree(mq->gru_mq_desc); 2992525789b4694d78df4f001063f042b2b74227d26Dean Nelsonout_1: 3006f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner kfree(mq); 3016f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerout_0: 3022525789b4694d78df4f001063f042b2b74227d26Dean Nelson return ERR_PTR(ret); 3035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 30494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 30533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonstatic void 3062525789b4694d78df4f001063f042b2b74227d26Dean Nelsonxpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq) 3075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 3082525789b4694d78df4f001063f042b2b74227d26Dean Nelson unsigned int mq_size; 3092525789b4694d78df4f001063f042b2b74227d26Dean Nelson int pg_order; 3102525789b4694d78df4f001063f042b2b74227d26Dean Nelson int ret; 3112525789b4694d78df4f001063f042b2b74227d26Dean Nelson 3122525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* disallow other partitions to access GRU mq */ 3132525789b4694d78df4f001063f042b2b74227d26Dean Nelson mq_size = 1UL << mq->order; 3142525789b4694d78df4f001063f042b2b74227d26Dean Nelson ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size); 3152525789b4694d78df4f001063f042b2b74227d26Dean Nelson BUG_ON(ret != xpSuccess); 3162525789b4694d78df4f001063f042b2b74227d26Dean Nelson 3172525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* unregister irq handler and release mq irq/vector mapping */ 3182525789b4694d78df4f001063f042b2b74227d26Dean Nelson free_irq(mq->irq, NULL); 3192525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_release_gru_mq_irq_uv(mq); 3205b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3212525789b4694d78df4f001063f042b2b74227d26Dean Nelson /* disable generation of irq when GRU mq op occurs to this mq */ 3222525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_gru_mq_watchlist_free_uv(mq); 3235b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3242525789b4694d78df4f001063f042b2b74227d26Dean Nelson pg_order = mq->order - PAGE_SHIFT; 3252525789b4694d78df4f001063f042b2b74227d26Dean Nelson free_pages((unsigned long)mq->address, pg_order); 3265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3272525789b4694d78df4f001063f042b2b74227d26Dean Nelson kfree(mq); 3285b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 3295b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3305b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic enum xp_retval 3316f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerxpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg, 3326f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner size_t msg_size) 33333ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson{ 3345b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson enum xp_retval xp_ret; 3355b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson int ret; 3365b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3375b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson while (1) { 3386f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size); 3395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (ret == MQE_OK) { 3405b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xp_ret = xpSuccess; 3415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson break; 3425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 3435b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (ret == MQE_QUEUE_FULL) { 3455b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson dev_dbg(xpc_chan, "gru_send_message_gpa() returned " 3465b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson "error=MQE_QUEUE_FULL\n"); 3475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* !!! handle QLimit reached; delay & try again */ 3485b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* ??? Do we add a limit to the number of retries? */ 3495b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson (void)msleep_interruptible(10); 3505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } else if (ret == MQE_CONGESTION) { 3515b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson dev_dbg(xpc_chan, "gru_send_message_gpa() returned " 3525b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson "error=MQE_CONGESTION\n"); 3535b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* !!! handle LB Overflow; simply try again */ 3545b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* ??? Do we add a limit to the number of retries? */ 3555b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } else { 3565b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* !!! Currently this is MQE_UNEXPECTED_CB_ERR */ 3575b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson dev_err(xpc_chan, "gru_send_message_gpa() returned " 3585b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson "error=%d\n", ret); 3595b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xp_ret = xpGruSendMqError; 3605b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson break; 3615b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 3625b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 3635b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return xp_ret; 3645b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 3655b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3665b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 3675b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_process_activate_IRQ_rcvd_uv(void) 3685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 3695b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long irq_flags; 3705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson short partid; 3715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition *part; 3725b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson u8 act_state_req; 3735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3745b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson DBUG_ON(xpc_activate_IRQ_rcvd == 0); 3755b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3765b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 3775b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 3785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part = &xpc_partitions[partid]; 3795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3805b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->sn.uv.act_state_req == 0) 3815b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson continue; 3825b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3835b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_activate_IRQ_rcvd--; 3845b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson BUG_ON(xpc_activate_IRQ_rcvd < 0); 3855b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3865b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson act_state_req = part->sn.uv.act_state_req; 3875b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part->sn.uv.act_state_req = 0; 3885b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 3895b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3905b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (act_state_req == XPC_P_ASR_ACTIVATE_UV) { 3915b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->act_state == XPC_P_AS_INACTIVE) 3925b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_activate_partition(part); 3935b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson else if (part->act_state == XPC_P_AS_DEACTIVATING) 3945b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_DEACTIVATE_PARTITION(part, xpReactivating); 3955b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 3965b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } else if (act_state_req == XPC_P_ASR_REACTIVATE_UV) { 3975b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->act_state == XPC_P_AS_INACTIVE) 3985b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_activate_partition(part); 3995b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson else 4005b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_DEACTIVATE_PARTITION(part, xpReactivating); 4015b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 4025b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } else if (act_state_req == XPC_P_ASR_DEACTIVATE_UV) { 4035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_DEACTIVATE_PARTITION(part, part->sn.uv.reason); 4045b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 4055b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } else { 4065b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson BUG(); 4075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 4085b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 4095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 4105b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (xpc_activate_IRQ_rcvd == 0) 4115b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson break; 4125b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 4135b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 4145b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 4155b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 4165b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 417bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 418bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_handle_activate_mq_msg_uv(struct xpc_partition *part, 419bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msghdr_uv *msg_hdr, 42009358972bff5ce99de496bbba97c85d417b3c054Robin Holt int part_setup, 421bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int *wakeup_hb_checker) 4225b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 4235b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long irq_flags; 424bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_partition_uv *part_uv = &part->sn.uv; 4255b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_openclose_args *args; 4265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 427bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->remote_act_state = msg_hdr->act_state; 4285b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 429bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson switch (msg_hdr->type) { 430bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV: 431bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* syncing of remote_act_state was just done above */ 432bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 4335b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 434bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { 435bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_activate_req_uv *msg; 4365b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 437bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* 438bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * ??? Do we deal here with ts_jiffies being different 439bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * ??? if act_state != XPC_P_AS_INACTIVE instead of 440bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * ??? below? 441bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 442bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 443bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_activate_req_uv, hdr); 4445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 445bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 446bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (part_uv->act_state_req == 0) 447bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_IRQ_rcvd++; 448bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; 449bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ 450bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; 451a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt part_uv->heartbeat_gpa = msg->heartbeat_gpa; 4526f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 4536f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (msg->activate_gru_mq_desc_gpa != 4546f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->activate_gru_mq_desc_gpa) { 4556f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 4566f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 4576f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 4586f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->activate_gru_mq_desc_gpa = 4596f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg->activate_gru_mq_desc_gpa; 4606f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 461bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 4625b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 463bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (*wakeup_hb_checker)++; 464bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 465bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 466bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: { 467bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_deactivate_req_uv *msg; 4685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 469bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 470bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_deactivate_req_uv, hdr); 4715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 472bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 473bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (part_uv->act_state_req == 0) 474bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_IRQ_rcvd++; 475bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 476bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->reason = msg->reason; 477bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 478bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 479bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (*wakeup_hb_checker)++; 480bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 481bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 482bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 483bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 4845b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 48509358972bff5ce99de496bbba97c85d417b3c054Robin Holt if (!part_setup) 48609358972bff5ce99de496bbba97c85d417b3c054Robin Holt break; 48709358972bff5ce99de496bbba97c85d417b3c054Robin Holt 488bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 489bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_chctl_closerequest_uv, 490bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson hdr); 491bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args = &part->remote_openclose_args[msg->ch_number]; 492bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args->reason = msg->reason; 4935b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 494bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 495bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREQUEST; 496bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 4975b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 498bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_wakeup_channel_mgr(part); 499bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 500bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 501bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 502bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 5035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 50409358972bff5ce99de496bbba97c85d417b3c054Robin Holt if (!part_setup) 50509358972bff5ce99de496bbba97c85d417b3c054Robin Holt break; 50609358972bff5ce99de496bbba97c85d417b3c054Robin Holt 507bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 508bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_chctl_closereply_uv, 509bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson hdr); 5105b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 511bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 512bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREPLY; 513bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 5145b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 515bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_wakeup_channel_mgr(part); 516bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 517bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 518bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 519bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 520bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 52109358972bff5ce99de496bbba97c85d417b3c054Robin Holt if (!part_setup) 52209358972bff5ce99de496bbba97c85d417b3c054Robin Holt break; 52309358972bff5ce99de496bbba97c85d417b3c054Robin Holt 524bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 525bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_chctl_openrequest_uv, 526bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson hdr); 527bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args = &part->remote_openclose_args[msg->ch_number]; 528bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args->entry_size = msg->entry_size; 529bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args->local_nentries = msg->local_nentries; 530bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 531bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 532bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREQUEST; 533bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 534bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 535bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_wakeup_channel_mgr(part); 536bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 537bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 538bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 539bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 540bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 54109358972bff5ce99de496bbba97c85d417b3c054Robin Holt if (!part_setup) 54209358972bff5ce99de496bbba97c85d417b3c054Robin Holt break; 54309358972bff5ce99de496bbba97c85d417b3c054Robin Holt 544bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(msg_hdr, struct 545bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_mq_msg_chctl_openreply_uv, hdr); 546bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args = &part->remote_openclose_args[msg->ch_number]; 547bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args->remote_nentries = msg->remote_nentries; 548bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson args->local_nentries = msg->local_nentries; 5496f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa; 550bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 551bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 552bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY; 553bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 554bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 555bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_wakeup_channel_mgr(part); 556bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 557bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 558efdd06ed181a88a11e612238c1ac04668e665395Robin Holt case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { 559efdd06ed181a88a11e612238c1ac04668e665395Robin Holt struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; 560efdd06ed181a88a11e612238c1ac04668e665395Robin Holt 56109358972bff5ce99de496bbba97c85d417b3c054Robin Holt if (!part_setup) 56209358972bff5ce99de496bbba97c85d417b3c054Robin Holt break; 56309358972bff5ce99de496bbba97c85d417b3c054Robin Holt 564efdd06ed181a88a11e612238c1ac04668e665395Robin Holt msg = container_of(msg_hdr, struct 565efdd06ed181a88a11e612238c1ac04668e665395Robin Holt xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); 566efdd06ed181a88a11e612238c1ac04668e665395Robin Holt spin_lock_irqsave(&part->chctl_lock, irq_flags); 567efdd06ed181a88a11e612238c1ac04668e665395Robin Holt part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE; 568efdd06ed181a88a11e612238c1ac04668e665395Robin Holt spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 569efdd06ed181a88a11e612238c1ac04668e665395Robin Holt 570efdd06ed181a88a11e612238c1ac04668e665395Robin Holt xpc_wakeup_channel_mgr(part); 571efdd06ed181a88a11e612238c1ac04668e665395Robin Holt } 572bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: 573bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 574bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->flags |= XPC_P_ENGAGED_UV; 575bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 576bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 577bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 578bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV: 579bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 580bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->flags &= ~XPC_P_ENGAGED_UV; 581bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 582bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 583bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 584bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson default: 585bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "received unknown activate_mq msg type=%d " 586bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "from partition=%d\n", msg_hdr->type, XPC_PARTID(part)); 587bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 588bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* get hb checker to deactivate from the remote partition */ 589bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 590bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (part_uv->act_state_req == 0) 591bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_IRQ_rcvd++; 592bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 593bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->reason = xpBadMsgType; 594bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 5955b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 596bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (*wakeup_hb_checker)++; 597bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 598bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 5995b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 600bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies && 601bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->remote_rp_ts_jiffies != 0) { 602bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* 603bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * ??? Does what we do here need to be sensitive to 604bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * ??? act_state or remote_act_state? 605bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 606bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 607bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (part_uv->act_state_req == 0) 608bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_IRQ_rcvd++; 609bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV; 610bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 6115b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 612bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (*wakeup_hb_checker)++; 613bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 614bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 615bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 616bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic irqreturn_t 617bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_handle_activate_IRQ_uv(int irq, void *dev_id) 618bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 619bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_activate_mq_msghdr_uv *msg_hdr; 620bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson short partid; 621bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_partition *part; 622bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int wakeup_hb_checker = 0; 6236f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner int part_referenced; 624bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 6252525789b4694d78df4f001063f042b2b74227d26Dean Nelson while (1) { 6266f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc); 6272525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (msg_hdr == NULL) 6282525789b4694d78df4f001063f042b2b74227d26Dean Nelson break; 629bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 630bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson partid = msg_hdr->partid; 631bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 632bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() " 633bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "received invalid partid=0x%x in message\n", 634bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson partid); 635bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } else { 636bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part = &xpc_partitions[partid]; 6376f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 6386f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_referenced = xpc_part_ref(part); 6396f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner xpc_handle_activate_mq_msg_uv(part, msg_hdr, 64009358972bff5ce99de496bbba97c85d417b3c054Robin Holt part_referenced, 6416f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner &wakeup_hb_checker); 6426f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (part_referenced) 643bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_part_deref(part); 6445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 6455b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6466f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr); 6475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 6485b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6495b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (wakeup_hb_checker) 6505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson wake_up_interruptible(&xpc_activate_IRQ_wq); 6515b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6525b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return IRQ_HANDLED; 6535b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 6545b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6555b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic enum xp_retval 6566f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerxpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc, 6576f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner unsigned long gru_mq_desc_gpa) 6586f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner{ 6596f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner enum xp_retval ret; 6606f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 6616f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa, 6626f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner sizeof(struct gru_message_queue_desc)); 6636f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (ret == xpSuccess) 6646f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_mq_desc->mq = NULL; 6656f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 6666f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner return ret; 6676f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner} 6686f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 6696f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerstatic enum xp_retval 6705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size, 6715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson int msg_type) 6725b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 6735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msghdr_uv *msg_hdr = msg; 6746f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct xpc_partition_uv *part_uv = &part->sn.uv; 6756f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct gru_message_queue_desc *gru_mq_desc; 6766f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner unsigned long irq_flags; 6776f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner enum xp_retval ret; 6785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV); 6805b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6815b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg_hdr->type = msg_type; 6826f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg_hdr->partid = xp_partition_id; 6835b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg_hdr->act_state = part->act_state; 6845b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies; 6855b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 6866f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); 6876f2584f47474d29ce829604bfc8b56c10b352fdbJack Steineragain: 6886f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) { 6896f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_mq_desc = part_uv->cached_activate_gru_mq_desc; 6906f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (gru_mq_desc == NULL) { 6916f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_mq_desc = kmalloc(sizeof(struct 6926f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_message_queue_desc), 6936f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner GFP_KERNEL); 6946f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (gru_mq_desc == NULL) { 6956f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xpNoMemory; 6966f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner goto done; 6976f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 6986f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->cached_activate_gru_mq_desc = gru_mq_desc; 6996f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 7006f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 7016f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc, 7026f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv-> 7036f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner activate_gru_mq_desc_gpa); 7046f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (ret != xpSuccess) 7056f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner goto done; 7066f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 7076f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 7086f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 7096f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 7106f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 7116f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 7125b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */ 7136f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg, 7146f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg_size); 7156f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (ret != xpSuccess) { 7166f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner smp_rmb(); /* ensure a fresh copy of part_uv->flags */ 7176f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) 7186f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner goto again; 7196f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner } 7206f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerdone: 7216f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex); 7226f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner return ret; 7235b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 7245b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7255b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 7265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_activate_IRQ_part_uv(struct xpc_partition *part, void *msg, 7275b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson size_t msg_size, int msg_type) 7285b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 7295b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson enum xp_retval ret; 7305b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7315b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type); 7325b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (unlikely(ret != xpSuccess)) 7335b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_DEACTIVATE_PARTITION(part, ret); 7345b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 7355b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7365b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 7375b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags, 7385b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson void *msg, size_t msg_size, int msg_type) 7395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 7406f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct xpc_partition *part = &xpc_partitions[ch->partid]; 7415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson enum xp_retval ret; 7425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7435b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type); 7445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (unlikely(ret != xpSuccess)) { 7455b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (irq_flags != NULL) 7465b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&ch->lock, *irq_flags); 7475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7485b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_DEACTIVATE_PARTITION(part, ret); 7495b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (irq_flags != NULL) 7515b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&ch->lock, *irq_flags); 7525b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 7535b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 7545b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7555b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 7565b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req) 7575b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 7585b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long irq_flags; 7595b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition_uv *part_uv = &part->sn.uv; 7605b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 76133ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson /* 7627d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson * !!! Make our side think that the remote partition sent an activate 763a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt * !!! mq message our way by doing what the activate IRQ handler would 764ea57f80c8c0e59cfc5095f7e856ce7c8e6ac2984Dean Nelson * !!! do had one really been sent. 76533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson */ 7665b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7675b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 7685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part_uv->act_state_req == 0) 7695b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_activate_IRQ_rcvd++; 7705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part_uv->act_state_req = act_state_req; 7715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 7725b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 7735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson wake_up_interruptible(&xpc_activate_IRQ_wq); 77433ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson} 77533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 77694bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelsonstatic enum xp_retval 7775b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, 7785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson size_t *len) 77994bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson{ 7807d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson s64 status; 7817d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson enum xp_retval ret; 7827d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson 7837d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson#if defined CONFIG_X86_64 7847d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa, 7857d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson (u64 *)len); 7867d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson if (status == BIOS_STATUS_SUCCESS) 7877d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpSuccess; 7887d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson else if (status == BIOS_STATUS_MORE_PASSES) 7897d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpNeedMoreInfo; 7907d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson else 7917d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpBiosError; 7927d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson 7937d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 7947d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len); 7957d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson if (status == SALRET_OK) 7967d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpSuccess; 7977d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson else if (status == SALRET_MORE_PASSES) 7987d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpNeedMoreInfo; 7997d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson else 8007d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson ret = xpSalError; 8017d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson 8027d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson#else 8037d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson #error not a supported configuration 8047d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson#endif 8057d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson 8067d9d1f25c3872080ce599e5dd0dac3305d0a028bDean Nelson return ret; 8075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 8085b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 8095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic int 810a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtxpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp) 8115b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 812a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv = 813a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat; 814a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv); 815a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt rp->sn.uv.activate_gru_mq_desc_gpa = 8166f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner uv_gpa(xpc_activate_mq_uv->gru_mq_desc); 8175b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return 0; 8185b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 8195b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 8205b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 821a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtxpc_allow_hb_uv(short partid) 8225b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 823a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt} 8245b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 825a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtstatic void 826a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtxpc_disallow_hb_uv(short partid) 827a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt{ 828a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt} 8295b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 830a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtstatic void 831a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holtxpc_disallow_all_hbs_uv(void) 832a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt{ 83394bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson} 83494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 83533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonstatic void 83633ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonxpc_increment_heartbeat_uv(void) 83733ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson{ 838a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv->value++; 8395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 8405b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 8415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 8425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_offline_heartbeat_uv(void) 8435b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 844a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_increment_heartbeat_uv(); 845a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv->offline = 1; 8465b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 8475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 8485b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 8495b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_online_heartbeat_uv(void) 8505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 851a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_increment_heartbeat_uv(); 852a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv->offline = 0; 85333ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson} 85433ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 85533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonstatic void 85633ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonxpc_heartbeat_init_uv(void) 85733ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson{ 858a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv->value = 1; 859a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_heartbeat_uv->offline = 0; 86033ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson} 86133ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 86233ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonstatic void 86333ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonxpc_heartbeat_exit_uv(void) 86433ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson{ 865a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_offline_heartbeat_uv(); 8665b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 8675b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 8685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic enum xp_retval 8695b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_get_remote_heartbeat_uv(struct xpc_partition *part) 8705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 8715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition_uv *part_uv = &part->sn.uv; 872a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt enum xp_retval ret; 8735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 874a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat), 875a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt part_uv->heartbeat_gpa, 876a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt sizeof(struct xpc_heartbeat_uv)); 877a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt if (ret != xpSuccess) 878a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt return ret; 8795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 880a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt if (part_uv->cached_heartbeat.value == part->last_heartbeat && 881a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt !part_uv->cached_heartbeat.offline) { 8825b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 883a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt ret = xpNoHeartbeat; 884a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt } else { 885a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt part->last_heartbeat = part_uv->cached_heartbeat.value; 8865b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 8875b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return ret; 88833ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson} 88933ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 89033ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelsonstatic void 891a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelsonxpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, 8925b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long remote_rp_gpa, int nasid) 89333ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson{ 89433ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson short partid = remote_rp->SAL_partid; 89533ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson struct xpc_partition *part = &xpc_partitions[partid]; 8965b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_activate_req_uv msg; 89733ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 8985b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ 8995b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; 900a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa; 9016f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner part->sn.uv.activate_gru_mq_desc_gpa = 902a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt remote_rp->sn.uv.activate_gru_mq_desc_gpa; 9035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 9045b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* 9055b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * ??? Is it a good idea to make this conditional on what is 9065b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * ??? potentially stale state information? 9075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson */ 9085b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { 9095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.rp_gpa = uv_gpa(xpc_rsvd_page); 910a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa; 9116f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg.activate_gru_mq_desc_gpa = 912a374c57b0764432a80303abee3d1afd1939b5a0aRobin Holt xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa; 9135b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 9145b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); 9155b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 91633ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 9175b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->act_state == XPC_P_AS_INACTIVE) 9185b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV); 91933ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson} 92033ba3c7724be79f7cdbfc611335572c056d9a05aDean Nelson 921a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelsonstatic void 922a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelsonxpc_request_partition_reactivation_uv(struct xpc_partition *part) 923a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelson{ 9245b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV); 9255b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 9265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 9275b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 9285b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_request_partition_deactivation_uv(struct xpc_partition *part) 9295b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 9305b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_deactivate_req_uv msg; 9315b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 9325b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* 9335b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * ??? Is it a good idea to make this conditional on what is 9345b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * ??? potentially stale state information? 9355b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson */ 9365b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->sn.uv.remote_act_state != XPC_P_AS_DEACTIVATING && 9375b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part->sn.uv.remote_act_state != XPC_P_AS_INACTIVE) { 9385b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 9395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.reason = part->reason; 9405b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 9415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV); 9425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 943a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelson} 944a47d5dac9d8481766382f8cf1483dd581df38b99Dean Nelson 945bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 946bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_cancel_partition_deactivation_request_uv(struct xpc_partition *part) 947bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 948bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* nothing needs to be done */ 949bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 950bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 951bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 952bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 953bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_init_fifo_uv(struct xpc_fifo_head_uv *head) 954bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 955bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->first = NULL; 956bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->last = NULL; 957bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_init(&head->lock); 958bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->n_entries = 0; 959bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 960bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 961bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void * 962bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head) 963bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 964bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 965bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_fifo_entry_uv *first; 966bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 967bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&head->lock, irq_flags); 968bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson first = head->first; 969bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (head->first != NULL) { 970bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->first = first->next; 971bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (head->first == NULL) 972bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->last = NULL; 97315b87d67ff3dc042bee42f991858d6b121b3b3caRobin Holt 97415b87d67ff3dc042bee42f991858d6b121b3b3caRobin Holt head->n_entries--; 97515b87d67ff3dc042bee42f991858d6b121b3b3caRobin Holt BUG_ON(head->n_entries < 0); 97615b87d67ff3dc042bee42f991858d6b121b3b3caRobin Holt 97715b87d67ff3dc042bee42f991858d6b121b3b3caRobin Holt first->next = NULL; 978bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 979bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&head->lock, irq_flags); 980bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return first; 981bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 982bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 983bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 984bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head, 985bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_fifo_entry_uv *last) 986bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 987bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 988bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 989bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson last->next = NULL; 990bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&head->lock, irq_flags); 991bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (head->last != NULL) 992bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->last->next = last; 993bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson else 994bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->first = last; 995bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson head->last = last; 9966f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner head->n_entries++; 997bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&head->lock, irq_flags); 998bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 999bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1000bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic int 1001bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head) 1002bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1003bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return head->n_entries; 1004bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1005bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1006e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson/* 10075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * Setup the channel structures that are uv specific. 1008e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson */ 1009e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelsonstatic enum xp_retval 1010a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtxpc_setup_ch_structures_uv(struct xpc_partition *part) 1011e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson{ 1012bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel_uv *ch_uv; 1013bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int ch_number; 1014bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1015bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (ch_number = 0; ch_number < part->nchannels; ch_number++) { 1016bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch_uv = &part->channels[ch_number].sn.uv; 1017bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1018bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 1019bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_init_fifo_uv(&ch_uv->recv_msg_list); 1020bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1021bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1022bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpSuccess; 1023e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson} 1024e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson 1025e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson/* 10265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * Teardown the channel structures that are uv specific. 1027e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson */ 1028e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelsonstatic void 1029a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtxpc_teardown_ch_structures_uv(struct xpc_partition *part) 1030e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson{ 1031bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* nothing needs to be done */ 1032e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson return; 1033e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson} 1034e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson 1035e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelsonstatic enum xp_retval 1036e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelsonxpc_make_first_contact_uv(struct xpc_partition *part) 1037e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson{ 10385b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_uv msg; 10395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10405b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* 10415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * We send a sync msg to get the remote partition's remote_act_state 10425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * updated to our current act_state which at this point should 10435b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson * be XPC_P_AS_ACTIVATING. 10445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson */ 10455b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 10465b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV); 10475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 1048dbd2918ec65c35f36bb102c88eafe87be0552f6fRobin Holt while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) || 1049dbd2918ec65c35f36bb102c88eafe87be0552f6fRobin Holt (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) { 10505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10515b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson dev_dbg(xpc_part, "waiting to make first contact with " 10525b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson "partition %d\n", XPC_PARTID(part)); 10535b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10545b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* wait a 1/4 of a second or so */ 10555b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson (void)msleep_interruptible(250); 10565b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10575b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (part->act_state == XPC_P_AS_DEACTIVATING) 10585b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return part->reason; 10595b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 10605b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10615b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return xpSuccess; 1062e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson} 1063e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson 1064e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelsonstatic u64 10657fb5e59d63deda89a8eefdbd5b3c8d622076afd4Dean Nelsonxpc_get_chctl_all_flags_uv(struct xpc_partition *part) 1066e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson{ 10675b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long irq_flags; 10685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson union xpc_channel_ctl_flags chctl; 10695b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10705b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 10715b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson chctl = part->chctl; 10725b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if (chctl.all_flags != 0) 10735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part->chctl.all_flags = 0; 10745b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10755b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 10765b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return chctl.all_flags; 10775b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 10785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 10795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic enum xp_retval 1080bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_allocate_send_msg_slot_uv(struct xpc_channel *ch) 1081bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1082bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1083bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot; 1084bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 1085bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int nentries; 1086bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int entry; 1087bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson size_t nbytes; 1088bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1089bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (nentries = ch->local_nentries; nentries > 0; nentries--) { 1090bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson nbytes = nentries * sizeof(struct xpc_send_msg_slot_uv); 1091bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch_uv->send_msg_slots = kzalloc(nbytes, GFP_KERNEL); 1092bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch_uv->send_msg_slots == NULL) 1093bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson continue; 1094bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1095bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (entry = 0; entry < nentries; entry++) { 1096bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot = &ch_uv->send_msg_slots[entry]; 1097bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1098bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->msg_slot_number = entry; 1099bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_put_fifo_entry_uv(&ch_uv->msg_slot_free_list, 1100bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson &msg_slot->next); 1101bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1102bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1103bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&ch->lock, irq_flags); 1104bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (nentries < ch->local_nentries) 1105bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch->local_nentries = nentries; 1106bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&ch->lock, irq_flags); 1107bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpSuccess; 1108bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1109bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1110bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpNoMemory; 1111bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1112bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1113bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic enum xp_retval 1114bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch) 1115bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1116bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1117bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg_slot; 1118bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 1119bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int nentries; 1120bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int entry; 1121bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson size_t nbytes; 1122bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1123bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 1124bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson nbytes = nentries * ch->entry_size; 1125bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch_uv->recv_msg_slots = kzalloc(nbytes, GFP_KERNEL); 1126bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch_uv->recv_msg_slots == NULL) 1127bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson continue; 1128bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1129bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (entry = 0; entry < nentries; entry++) { 1130361916a943cd9dbda1c0b00879d0225cc919d868Dean Nelson msg_slot = ch_uv->recv_msg_slots + 1131361916a943cd9dbda1c0b00879d0225cc919d868Dean Nelson entry * ch->entry_size; 1132bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1133bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->hdr.msg_slot_number = entry; 1134bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1135bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1136bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&ch->lock, irq_flags); 1137bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (nentries < ch->remote_nentries) 1138bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch->remote_nentries = nentries; 1139bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&ch->lock, irq_flags); 1140bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpSuccess; 1141bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1142bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1143bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpNoMemory; 1144bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1145bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1146bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson/* 1147bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * Allocate msg_slots associated with the channel. 1148bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 1149bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic enum xp_retval 11505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_setup_msg_structures_uv(struct xpc_channel *ch) 11515b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 1152bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson static enum xp_retval ret; 1153bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1154bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1155bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson DBUG_ON(ch->flags & XPC_C_SETUP); 1156bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 11576f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct 11586f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_message_queue_desc), 11596f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner GFP_KERNEL); 11606f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner if (ch_uv->cached_notify_gru_mq_desc == NULL) 11616f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner return xpNoMemory; 11626f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 1163bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpc_allocate_send_msg_slot_uv(ch); 1164bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret == xpSuccess) { 1165bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1166bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpc_allocate_recv_msg_slot_uv(ch); 1167bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret != xpSuccess) { 1168bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson kfree(ch_uv->send_msg_slots); 1169bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 1170bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1171bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1172bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return ret; 11735b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 11745b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 1175bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson/* 1176bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * Free up msg_slots and clear other stuff that were setup for the specified 1177bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * channel. 1178bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 11795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 11805b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_teardown_msg_structures_uv(struct xpc_channel *ch) 11815b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 11825b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_channel_uv *ch_uv = &ch->sn.uv; 11835b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 1184bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson DBUG_ON(!spin_is_locked(&ch->lock)); 1185bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 11866f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner kfree(ch_uv->cached_notify_gru_mq_desc); 11876f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ch_uv->cached_notify_gru_mq_desc = NULL; 11885b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 1189bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch->flags & XPC_C_SETUP) { 1190bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 1191bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson kfree(ch_uv->send_msg_slots); 1192bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_init_fifo_uv(&ch_uv->recv_msg_list); 1193bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson kfree(ch_uv->recv_msg_slots); 1194bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 11955b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 11965b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 11975b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 11985b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_chctl_closerequest_uv(struct xpc_channel *ch, unsigned long *irq_flags) 11995b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12005b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_chctl_closerequest_uv msg; 12015b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12025b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.ch_number = ch->number; 12035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.reason = ch->reason; 12045b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 12055b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV); 12065b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12085b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_chctl_closereply_uv(struct xpc_channel *ch, unsigned long *irq_flags) 12105b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12115b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_chctl_closereply_uv msg; 12125b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12135b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.ch_number = ch->number; 12145b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 12155b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV); 12165b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12175b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12185b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12195b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_chctl_openrequest_uv(struct xpc_channel *ch, unsigned long *irq_flags) 12205b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12215b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_chctl_openrequest_uv msg; 12225b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12235b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.ch_number = ch->number; 1224bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg.entry_size = ch->entry_size; 12255b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.local_nentries = ch->local_nentries; 12265b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 12275b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV); 12285b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12295b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12305b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12315b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags) 12325b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12335b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_chctl_openreply_uv msg; 12345b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12355b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.ch_number = ch->number; 12365b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.local_nentries = ch->local_nentries; 12375b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson msg.remote_nentries = ch->remote_nentries; 12386f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc); 12395b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 12405b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV); 12415b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12425b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12435b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 1244efdd06ed181a88a11e612238c1ac04668e665395Robin Holtxpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1245efdd06ed181a88a11e612238c1ac04668e665395Robin Holt{ 1246efdd06ed181a88a11e612238c1ac04668e665395Robin Holt struct xpc_activate_mq_msg_chctl_opencomplete_uv msg; 1247efdd06ed181a88a11e612238c1ac04668e665395Robin Holt 1248efdd06ed181a88a11e612238c1ac04668e665395Robin Holt msg.ch_number = ch->number; 1249efdd06ed181a88a11e612238c1ac04668e665395Robin Holt xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1250efdd06ed181a88a11e612238c1ac04668e665395Robin Holt XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV); 1251efdd06ed181a88a11e612238c1ac04668e665395Robin Holt} 1252efdd06ed181a88a11e612238c1ac04668e665395Robin Holt 1253efdd06ed181a88a11e612238c1ac04668e665395Robin Holtstatic void 1254bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) 1255bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1256bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 1257bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1258bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&part->chctl_lock, irq_flags); 1259bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part->chctl.flags[ch_number] |= XPC_CHCTL_MSGREQUEST; 1260bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 1261bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1262bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_wakeup_channel_mgr(part); 1263bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1264bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 12656f2584f47474d29ce829604bfc8b56c10b352fdbJack Steinerstatic enum xp_retval 12665b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch, 12676f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner unsigned long gru_mq_desc_gpa) 12685b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12696f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner struct xpc_channel_uv *ch_uv = &ch->sn.uv; 12706f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner 12716f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL); 12726f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc, 12736f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_mq_desc_gpa); 12745b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12755b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12765b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12775b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_indicate_partition_engaged_uv(struct xpc_partition *part) 12785b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12795b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_uv msg; 12805b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12815b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 12825b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV); 12835b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12845b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12855b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12865b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_indicate_partition_disengaged_uv(struct xpc_partition *part) 12875b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12885b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_activate_mq_msg_uv msg; 12895b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12905b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 12915b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV); 12925b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 12935b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 12945b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic void 12955b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_assume_partition_disengaged_uv(short partid) 12965b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 12975b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition_uv *part_uv = &xpc_partitions[partid].sn.uv; 12985b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson unsigned long irq_flags; 12995b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 13005b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 13015b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part_uv->flags &= ~XPC_P_ENGAGED_UV; 13025b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 13035b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 13045b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 13055b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic int 13065b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_partition_engaged_uv(short partid) 13075b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 13085b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return (xpc_partitions[partid].sn.uv.flags & XPC_P_ENGAGED_UV) != 0; 13095b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 13105b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 13115b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic int 13125b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxpc_any_partition_engaged_uv(void) 13135b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 13145b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson struct xpc_partition_uv *part_uv; 13155b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson short partid; 13165b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 13175b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 13185b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson part_uv = &xpc_partitions[partid].sn.uv; 13195b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson if ((part_uv->flags & XPC_P_ENGAGED_UV) != 0) 13205b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return 1; 13215b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson } 13225b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return 0; 1323e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson} 1324e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson 1325bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic enum xp_retval 1326bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_allocate_msg_slot_uv(struct xpc_channel *ch, u32 flags, 1327bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv **address_of_msg_slot) 1328bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1329bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson enum xp_retval ret; 1330bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot; 1331bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_fifo_entry_uv *entry; 1332bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1333bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson while (1) { 1334bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson entry = xpc_get_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list); 1335bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (entry != NULL) 1336bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 1337bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1338bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (flags & XPC_NOWAIT) 1339bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpNoWait; 1340bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1341bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpc_allocate_msg_wait(ch); 1342bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret != xpInterrupted && ret != xpTimeout) 1343bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return ret; 1344bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1345bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1346bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot = container_of(entry, struct xpc_send_msg_slot_uv, next); 1347bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson *address_of_msg_slot = msg_slot; 1348bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpSuccess; 1349bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1350bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1351bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1352bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_free_msg_slot_uv(struct xpc_channel *ch, 1353bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot) 1354bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1355bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_put_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list, &msg_slot->next); 1356bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1357bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* wakeup anyone waiting for a free msg slot */ 1358bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) 1359bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson wake_up(&ch->msg_allocate_wq); 1360bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1361bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1362bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1363bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_notify_sender_uv(struct xpc_channel *ch, 1364bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot, 1365bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson enum xp_retval reason) 1366bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1367bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_notify_func func = msg_slot->func; 1368bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1369bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (func != NULL && cmpxchg(&msg_slot->func, func, NULL) == func) { 1370bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1371bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson atomic_dec(&ch->n_to_notify); 1372bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1373bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_dbg(xpc_chan, "msg_slot->func() called, msg_slot=0x%p " 1374bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 1375bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->msg_slot_number, ch->partid, ch->number); 1376bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1377bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson func(reason, ch->partid, ch->number, msg_slot->key); 1378bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1379bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_dbg(xpc_chan, "msg_slot->func() returned, msg_slot=0x%p " 1380bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 1381bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->msg_slot_number, ch->partid, ch->number); 1382bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1383bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1384bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1385bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1386bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_handle_notify_mq_ack_uv(struct xpc_channel *ch, 1387bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg) 1388bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1389bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot; 1390bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int entry = msg->hdr.msg_slot_number % ch->local_nentries; 1391bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1392bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot = &ch->sn.uv.send_msg_slots[entry]; 1393bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1394bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson BUG_ON(msg_slot->msg_slot_number != msg->hdr.msg_slot_number); 1395bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->msg_slot_number += ch->local_nentries; 1396bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1397bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (msg_slot->func != NULL) 1398bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_notify_sender_uv(ch, msg_slot, xpMsgDelivered); 1399bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1400bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_free_msg_slot_uv(ch, msg_slot); 1401bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1402bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1403bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1404bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_handle_notify_mq_msg_uv(struct xpc_partition *part, 1405bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg) 1406bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1407bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_partition_uv *part_uv = &part->sn.uv; 1408bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel *ch; 1409bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel_uv *ch_uv; 1410bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg_slot; 1411bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson unsigned long irq_flags; 1412bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int ch_number = msg->hdr.ch_number; 1413bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1414bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (unlikely(ch_number >= part->nchannels)) { 1415bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received invalid " 1416bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "channel number=0x%x in message from partid=%d\n", 1417bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch_number, XPC_PARTID(part)); 1418bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1419bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* get hb checker to deactivate from the remote partition */ 1420bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 1421bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (part_uv->act_state_req == 0) 1422bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_IRQ_rcvd++; 1423bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 1424bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part_uv->reason = xpBadChannelNumber; 1425bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 1426bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1427bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson wake_up_interruptible(&xpc_activate_IRQ_wq); 1428bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 1429bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1430bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1431bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch = &part->channels[ch_number]; 1432bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_ref(ch); 1433bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1434bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (!(ch->flags & XPC_C_CONNECTED)) { 1435bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_deref(ch); 1436bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 1437bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1438bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1439bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* see if we're really dealing with an ACK for a previously sent msg */ 1440bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (msg->hdr.size == 0) { 1441bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_handle_notify_mq_ack_uv(ch, msg); 1442bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_deref(ch); 1443bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return; 1444bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1445bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1446bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* we're dealing with a normal message sent via the notify_mq */ 1447bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ch_uv = &ch->sn.uv; 1448bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1449361916a943cd9dbda1c0b00879d0225cc919d868Dean Nelson msg_slot = ch_uv->recv_msg_slots + 1450361916a943cd9dbda1c0b00879d0225cc919d868Dean Nelson (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; 1451bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1452bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson BUG_ON(msg_slot->hdr.size != 0); 1453bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1454bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson memcpy(msg_slot, msg, msg->hdr.size); 1455bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1456bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_put_fifo_entry_uv(&ch_uv->recv_msg_list, &msg_slot->hdr.u.next); 1457bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1458bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) { 1459bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* 1460bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * If there is an existing idle kthread get it to deliver 1461bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * the payload, otherwise we'll have to get the channel mgr 1462bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * for this partition to create a kthread to do the delivery. 1463bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 1464bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (atomic_read(&ch->kthreads_idle) > 0) 1465bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson wake_up_nr(&ch->idle_wq, 1); 1466bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson else 1467bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_send_chctl_local_msgrequest_uv(part, ch->number); 1468bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1469bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_deref(ch); 1470bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1471bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1472bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic irqreturn_t 1473bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_handle_notify_IRQ_uv(int irq, void *dev_id) 1474bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1475bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg; 1476bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson short partid; 1477bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_partition *part; 1478bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 14796f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) != 14806f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner NULL) { 1481bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1482bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson partid = msg->hdr.partid; 1483bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 1484bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received " 1485bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson "invalid partid=0x%x in message\n", partid); 1486bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } else { 1487bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson part = &xpc_partitions[partid]; 1488bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1489bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (xpc_part_ref(part)) { 1490bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_handle_notify_mq_msg_uv(part, msg); 1491bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_part_deref(part); 1492bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1493bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1494bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 14956f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg); 1496bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1497bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1498bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return IRQ_HANDLED; 1499bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1500bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1501bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic int 1502bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_n_of_deliverable_payloads_uv(struct xpc_channel *ch) 1503bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1504bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpc_n_of_fifo_entries_uv(&ch->sn.uv.recv_msg_list); 1505bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1506bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1507bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1508bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_process_msg_chctl_flags_uv(struct xpc_partition *part, int ch_number) 1509bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1510bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_channel *ch = &part->channels[ch_number]; 1511bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int ndeliverable_payloads; 1512bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1513bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_ref(ch); 1514bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1515bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ndeliverable_payloads = xpc_n_of_deliverable_payloads_uv(ch); 1516bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1517bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ndeliverable_payloads > 0 && 1518bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (ch->flags & XPC_C_CONNECTED) && 1519bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)) { 1520bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1521bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_activate_kthreads(ch, ndeliverable_payloads); 1522bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1523bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1524bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_deref(ch); 1525bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1526bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1527bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic enum xp_retval 1528bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload, 1529bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson u16 payload_size, u8 notify_type, xpc_notify_func func, 1530bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson void *key) 1531bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1532bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson enum xp_retval ret = xpSuccess; 1533bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot = NULL; 1534bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg; 1535bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson u8 msg_buffer[XPC_NOTIFY_MSG_SIZE_UV]; 1536bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson size_t msg_size; 1537bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1538bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson DBUG_ON(notify_type != XPC_N_CALL); 1539bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1540bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_size = sizeof(struct xpc_notify_mq_msghdr_uv) + payload_size; 1541bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (msg_size > ch->entry_size) 1542bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return xpPayloadTooBig; 1543bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1544bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_ref(ch); 1545bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1546bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch->flags & XPC_C_DISCONNECTING) { 1547bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = ch->reason; 1548bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_1; 1549bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1550bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (!(ch->flags & XPC_C_CONNECTED)) { 1551bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpNotConnected; 1552bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_1; 1553bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1554bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1555bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpc_allocate_msg_slot_uv(ch, flags, &msg_slot); 1556bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret != xpSuccess) 1557bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_1; 1558bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1559bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (func != NULL) { 1560bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson atomic_inc(&ch->n_to_notify); 1561bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1562bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->key = key; 156369b3bb65fa97a1e8563518dbbc35cd57beefb2d4Robin Holt smp_wmb(); /* a non-NULL func must hit memory after the key */ 1564bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->func = func; 1565bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1566bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ch->flags & XPC_C_DISCONNECTING) { 1567bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = ch->reason; 1568bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_2; 1569bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1570bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1571bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1572bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = (struct xpc_notify_mq_msg_uv *)&msg_buffer; 1573bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.partid = xp_partition_id; 1574bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.ch_number = ch->number; 1575bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.size = msg_size; 1576bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.msg_slot_number = msg_slot->msg_slot_number; 1577bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson memcpy(&msg->payload, payload, payload_size); 1578bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 15796f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, 15806f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner msg_size); 1581bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret == xpSuccess) 1582bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_1; 1583bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1584bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1585bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonout_2: 1586bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (func != NULL) { 1587bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* 1588bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * Try to NULL the msg_slot's func field. If we fail, then 1589bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * xpc_notify_senders_of_disconnect_uv() beat us to it, in which 1590bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * case we need to pretend we succeeded to send the message 1591bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * since the user will get a callout for the disconnect error 1592bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * by xpc_notify_senders_of_disconnect_uv(), and to also get an 1593bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * error returned here will confuse them. Additionally, since 1594bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * in this case the channel is being disconnected we don't need 1595bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * to put the the msg_slot back on the free list. 1596bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 1597bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (cmpxchg(&msg_slot->func, func, NULL) != func) { 1598bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson ret = xpSuccess; 1599bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson goto out_1; 1600bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1601bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1602bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot->key = NULL; 1603bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson atomic_dec(&ch->n_to_notify); 1604bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1605bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_free_msg_slot_uv(ch, msg_slot); 1606bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonout_1: 1607bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_msgqueue_deref(ch); 1608bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return ret; 1609bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1610bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1611bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson/* 1612bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * Tell the callers of xpc_send_notify() that the status of their payloads 1613bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * is unknown because the channel is now disconnecting. 1614bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * 1615bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * We don't worry about putting these msg_slots on the free list since the 1616bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * msg_slots themselves are about to be kfree'd. 1617bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 1618bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1619bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_notify_senders_of_disconnect_uv(struct xpc_channel *ch) 1620bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1621bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_send_msg_slot_uv *msg_slot; 1622bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson int entry; 1623bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1624bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING)); 1625bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1626bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson for (entry = 0; entry < ch->local_nentries; entry++) { 1627bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1628bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (atomic_read(&ch->n_to_notify) == 0) 1629bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson break; 1630bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1631bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg_slot = &ch->sn.uv.send_msg_slots[entry]; 1632bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (msg_slot->func != NULL) 1633bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_notify_sender_uv(ch, msg_slot, ch->reason); 1634bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1635bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1636bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1637bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson/* 1638bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson * Get the next deliverable message's payload. 1639bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson */ 1640bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void * 1641bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_get_deliverable_payload_uv(struct xpc_channel *ch) 1642bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson{ 1643bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_fifo_entry_uv *entry; 1644bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg; 1645bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson void *payload = NULL; 1646bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1647bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (!(ch->flags & XPC_C_DISCONNECTING)) { 1648bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson entry = xpc_get_fifo_entry_uv(&ch->sn.uv.recv_msg_list); 1649bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (entry != NULL) { 1650bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(entry, struct xpc_notify_mq_msg_uv, 1651bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson hdr.u.next); 1652bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson payload = &msg->payload; 1653bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1654bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1655bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return payload; 1656bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson} 1657bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1658bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonstatic void 1659bd3e64c1759e4930315ebf022611468ee9621486Dean Nelsonxpc_received_payload_uv(struct xpc_channel *ch, void *payload) 1660e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson{ 1661bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson struct xpc_notify_mq_msg_uv *msg; 1662bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson enum xp_retval ret; 1663bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1664bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg = container_of(payload, struct xpc_notify_mq_msg_uv, payload); 1665bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1666bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson /* return an ACK to the sender of this message */ 1667bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1668bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.partid = xp_partition_id; 1669bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson msg->hdr.size = 0; /* size of zero indicates this is an ACK */ 1670bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 16716f2584f47474d29ce829604bfc8b56c10b352fdbJack Steiner ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, 1672bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson sizeof(struct xpc_notify_mq_msghdr_uv)); 1673bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (ret != xpSuccess) 1674bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1675e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson} 1676e17d416b1bc947df68499863f13b401fb42b48f6Dean Nelson 1677a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holtstatic struct xpc_arch_operations xpc_arch_ops_uv = { 1678a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .setup_partitions = xpc_setup_partitions_uv, 1679a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .teardown_partitions = xpc_teardown_partitions_uv, 1680a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv, 1681a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv, 1682a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .setup_rsvd_page = xpc_setup_rsvd_page_uv, 1683a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1684a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .allow_hb = xpc_allow_hb_uv, 1685a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .disallow_hb = xpc_disallow_hb_uv, 1686a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .disallow_all_hbs = xpc_disallow_all_hbs_uv, 1687a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .increment_heartbeat = xpc_increment_heartbeat_uv, 1688a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .offline_heartbeat = xpc_offline_heartbeat_uv, 1689a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .online_heartbeat = xpc_online_heartbeat_uv, 1690a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .heartbeat_init = xpc_heartbeat_init_uv, 1691a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .heartbeat_exit = xpc_heartbeat_exit_uv, 1692a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .get_remote_heartbeat = xpc_get_remote_heartbeat_uv, 1693a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1694a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .request_partition_activation = 1695a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt xpc_request_partition_activation_uv, 1696a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .request_partition_reactivation = 1697a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt xpc_request_partition_reactivation_uv, 1698a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .request_partition_deactivation = 1699a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt xpc_request_partition_deactivation_uv, 1700a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .cancel_partition_deactivation_request = 1701a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt xpc_cancel_partition_deactivation_request_uv, 1702a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1703a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .setup_ch_structures = xpc_setup_ch_structures_uv, 1704a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .teardown_ch_structures = xpc_teardown_ch_structures_uv, 1705a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1706a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .make_first_contact = xpc_make_first_contact_uv, 1707a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1708a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .get_chctl_all_flags = xpc_get_chctl_all_flags_uv, 1709a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_chctl_closerequest = xpc_send_chctl_closerequest_uv, 1710a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_chctl_closereply = xpc_send_chctl_closereply_uv, 1711a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_chctl_openrequest = xpc_send_chctl_openrequest_uv, 1712a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_chctl_openreply = xpc_send_chctl_openreply_uv, 1713a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv, 1714a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv, 1715a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1716a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv, 1717a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1718a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .setup_msg_structures = xpc_setup_msg_structures_uv, 1719a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .teardown_msg_structures = xpc_teardown_msg_structures_uv, 1720a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1721a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .indicate_partition_engaged = xpc_indicate_partition_engaged_uv, 1722a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv, 1723a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .assume_partition_disengaged = xpc_assume_partition_disengaged_uv, 1724a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .partition_engaged = xpc_partition_engaged_uv, 1725a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .any_partition_engaged = xpc_any_partition_engaged_uv, 1726a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 1727a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv, 1728a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .send_payload = xpc_send_payload_uv, 1729a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .get_deliverable_payload = xpc_get_deliverable_payload_uv, 1730a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .received_payload = xpc_received_payload_uv, 1731a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, 1732a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt}; 1733a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt 17345b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonint 173594bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelsonxpc_init_uv(void) 173694bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson{ 1737a7665b0a380585fbd70a2275f3120c6086e0c92dRobin Holt xpc_arch_ops = xpc_arch_ops_uv; 1738bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 1739bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { 1740bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n", 1741bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson XPC_MSG_HDR_MAX_SIZE); 1742bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson return -E2BIG; 1743bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 17445b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 17452525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, 17462525789b4694d78df4f001063f042b2b74227d26Dean Nelson XPC_ACTIVATE_IRQ_NAME, 17475b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xpc_handle_activate_IRQ_uv); 17482525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (IS_ERR(xpc_activate_mq_uv)) 17492525789b4694d78df4f001063f042b2b74227d26Dean Nelson return PTR_ERR(xpc_activate_mq_uv); 17505b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 17512525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, 17522525789b4694d78df4f001063f042b2b74227d26Dean Nelson XPC_NOTIFY_IRQ_NAME, 1753bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson xpc_handle_notify_IRQ_uv); 17542525789b4694d78df4f001063f042b2b74227d26Dean Nelson if (IS_ERR(xpc_notify_mq_uv)) { 17552525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); 17562525789b4694d78df4f001063f042b2b74227d26Dean Nelson return PTR_ERR(xpc_notify_mq_uv); 1757bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson } 1758bd3e64c1759e4930315ebf022611468ee9621486Dean Nelson 17595b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return 0; 176094bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson} 176194bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson 176294bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelsonvoid 176394bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelsonxpc_exit_uv(void) 176494bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson{ 17652525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); 17662525789b4694d78df4f001063f042b2b74227d26Dean Nelson xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); 176794bd2708d4a95d7da5a1c7c28a063eccd127fb69Dean Nelson} 1768