1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
from __future__ import print_function
import argparse
import os
import subprocess
import sys
import tempfile
import tools_version
PROG = 'mstprivhost'
TOOL_VERSION = "1.0.0"
CMD_HELP = """\
restrict: Set host 1 (ARM) privileged, host 0 (x86_64) restricted.
privilege: Set host 1 (ARM) privileged, host 0 (x86_64) privileged
(back to default).
"""
DESCRIPTION = """\
restrict or privilege host
Note: New configurations takes effect immediately.
Note: privileged host - host has all supported privileges.
restricted host - host is not allowed to modify global
per port/parameters or access other hosts parametersis.
"""
DISABLE_RSHIM_HELP = """\
When TRUE, the host does not have an RSHIM function
to access the embedded CPU registers
mlxconfig_name: HOST_DISABLE_RSHIM
"""
DISABLE_TRACER_HELP = """\
When TRUE, the host will not be allowed to own the Tracer
mlxconfig_name: HOST_DISABLE_TRACER_OWNER
"""
DISABLE_COUNTER_RD_HELP = """\
When TRUE, the host will not be allowed to read Physical port counters
mlxconfig_name: HOST_DISABLE_PORT_COUNTER
"""
DISABLE_PORT_OWNER_HELP = """\
When TRUE, the host will not be allowed to be Port Owner
mlxconfig_name: HOST_DISABLE_PORT_OWNER
"""
def _log(level, msg, *args, **kw):
if args:
msg = msg % args
print(level, msg, end=kw.get('end', '\n'))
def info(msg, *args, **kw):
_log("-I-", msg, *args, **kw)
def error(msg, *args, **kw):
_log("-E-", msg, *args, **kw)
class PrivilegeException(Exception):
pass
class PrivilegeMgr(object):
CONFIG_CMD_LINE = "mlxconfig -d %s -f %s --yes set_raw"
MCRA_CMD_LINE = "mcra %s 0xf0014.0:16"
BLUE_FIELD_DEV_ID = 0x211
TITLE = "MLNX_RAW_TLV_FILE\n"
RAW_BYTES = "0x03000204 0x07000083 0x00000000"
LIMITED = 0x10000000
DISABLE_PORT_OWNER = 0x01
DISABLE_COUNTER_RD = 0x02
DISABLE_TRACER = 0x04
DISABLE_RSHIM = 0x08
RESTRICT_BYTES = "0x03000204 0x07000083 0x00000000 0x1000000f"
PRIVILEGE_BYTES = "0x03000204 0x07000083 0x00000000 0x00000000"
def __init__(self, device, privilege, disable_rshim, disable_tracer,
disable_counter_rd, disable_port_owner):
self._privilege = privilege
self._device = device
self._file_p = tempfile.NamedTemporaryFile(
suffix='.raw', prefix="nvconfig_setting_")
self._file_name = self._file_p.name
self._nv_host_priv_conf = 0
if not self._privilege:
self._nv_host_priv_conf = self.LIMITED
if disable_rshim:
self._nv_host_priv_conf |= self.DISABLE_RSHIM
if disable_tracer:
self._nv_host_priv_conf |= self.DISABLE_TRACER
if disable_counter_rd:
self._nv_host_priv_conf |= self.DISABLE_COUNTER_RD
if disable_port_owner:
self._nv_host_priv_conf |= self.DISABLE_PORT_OWNER
def prepare(self):
info("preparing configuration file...", end='')
self._file_p.write(self.TITLE)
nv_host_priv_conf_str = '0x%08x' % self._nv_host_priv_conf
conf_bytes = " ".join((self.RAW_BYTES, nv_host_priv_conf_str))
self._file_p.write(conf_bytes)
self._file_p.flush()
print("Done!")
@staticmethod
def _exec_cmd(cmd):
p = subprocess.Popen(cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
shell=True)
stdout, stderr = p.communicate()
exit_code = p.wait()
return (exit_code, stdout, stderr)
def configure(self):
info("configuring device...", end='')
cmd = self.CONFIG_CMD_LINE % (self._device, self._file_name)
exit_code, stdout, stderr = self._exec_cmd(cmd)
if exit_code != 0:
print("Failed")
print(stdout + stderr)
else:
print("Done!")
return exit_code
def cleanup(self):
self._file_p.close()
if os.path.isfile(self._file_name):
os.remove(self._file_name)
def validate(self):
# get device ID
cmd_line = self.MCRA_CMD_LINE % self._device
exit_code, stdout, _ = self._exec_cmd(cmd_line)
if exit_code != 0:
raise PrivilegeException("Unknow device '%s'!" % self._device)
dev_id = int(stdout, 16)
if dev_id != self.BLUE_FIELD_DEV_ID:
raise PrivilegeException(
"Device '%s' is not supported, "
"only BlueField devices are supported!" % self._device)
def parse_args():
parser = argparse.ArgumentParser(
prog=PROG, description=DESCRIPTION,
formatter_class=argparse.RawTextHelpFormatter,
version=tools_version.GetVersionString(PROG, TOOL_VERSION))
# options arguments
options_group = parser.add_argument_group('Options')
options_group.add_argument(
'--device',
'-d',
required=True,
help='Device to work with.')
# command arguments
command_group = parser.add_argument_group('Commands')
command_group.add_argument(
'command',
nargs=1,
choices=["r", "restrict", "p", "privilege"],
help=CMD_HELP)
options_group.add_argument('--disable_rshim', action="store_true",
help=DISABLE_RSHIM_HELP)
options_group.add_argument('--disable_tracer', action="store_true",
help=DISABLE_TRACER_HELP)
options_group.add_argument('--disable_counter_rd', action="store_true",
help=DISABLE_COUNTER_RD_HELP)
options_group.add_argument('--disable_port_owner', action="store_true",
help=DISABLE_PORT_OWNER_HELP)
args = parser.parse_args()
if args.command[0] in ("p", "privilege"):
if args.disable_rshim or args.disable_tracer or \
args.disable_counter_rd or args.disable_port_owner:
parser.error("disable flags are not allowed in privilege mode")
return args
def main():
args = parse_args()
device = args.device
command = args.command[0]
if command in ("p", "privilege"):
privilege = True
elif command in ("r", "restrict"):
privilege = False
retcode = 0
mgr = PrivilegeMgr(device, privilege, args.disable_rshim,
args.disable_tracer, args.disable_counter_rd,
args.disable_port_owner)
try:
mgr.validate()
mgr.prepare()
retcode = mgr.configure()
except PrivilegeException as exc:
error(str(exc))
retcode = 1
except Exception as exc:
error("got an error: %s", str(exc))
retcode = 1
except(KeyboardInterrupt, SystemExit):
print("\nInterrupted!\nExiting")
retcode = 1
finally:
mgr.cleanup()
return retcode
if __name__ == "__main__":
sys.exit(main())
|