^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) Copyright 2020 Hewlett Packard Enterprise Development LP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Cross Partition (XP) uv-based functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Architecture specific implementation of common functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/uv/uv_hub.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #if defined CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/uv/bios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #elif defined CONFIG_IA64_SGI_UV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/sn/sn_sal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "../sgi-gru/grukservices.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "xp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Convert a virtual memory address to a physical memory address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) xp_pa_uv(void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return uv_gpa(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Convert a global physical to socket physical address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) xp_socket_pa_uv(unsigned long gpa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return uv_gpa_to_soc_phys_ram(gpa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static enum xp_retval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) BUG_ON(len != 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ret = gru_read_gpa(dst_va, src_gpa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return xpSuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "len=%ld\n", dst_gpa, src_gpa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return xpGruCopyError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static enum xp_retval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (uv_gpa_in_mmr_space(src_gpa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return xp_remote_mmr_read(dst_gpa, src_gpa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ret = gru_copy_gpa(dst_gpa, src_gpa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return xpSuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "len=%ld\n", dst_gpa, src_gpa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return xpGruCopyError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) xp_cpu_to_nasid_uv(int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static enum xp_retval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #if defined CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ret != BIOS_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dev_err(xp, "uv_bios_change_memprotect(,, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return xpBiosError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #elif defined CONFIG_IA64_SGI_UV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u64 nasid_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) &nasid_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dev_err(xp, "sn_change_memprotect(,, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return xpSalError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #error not a supported configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return xpSuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static enum xp_retval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #if defined CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ret = uv_bios_change_memprotect(phys_addr, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) UV_MEMPROT_RESTRICT_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret != BIOS_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dev_err(xp, "uv_bios_change_memprotect(,, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return xpBiosError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #elif defined CONFIG_IA64_SGI_UV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u64 nasid_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) &nasid_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_err(xp, "sn_change_memprotect(,, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return xpSalError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #error not a supported configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return xpSuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) enum xp_retval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) xp_init_uv(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) WARN_ON(!is_uv_system());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!is_uv_system())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return xpUnsupported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) xp_partition_id = sn_partition_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) xp_region_size = sn_region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) xp_pa = xp_pa_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) xp_socket_pa = xp_socket_pa_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) xp_remote_memcpy = xp_remote_memcpy_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) xp_expand_memprotect = xp_expand_memprotect_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) xp_restrict_memprotect = xp_restrict_memprotect_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return xpSuccess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) xp_exit_uv(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) WARN_ON(!is_uv_system());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }