cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xp_uv.c (4042B)


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