mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
279 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7770b7a2c0 | ||
|
|
2ef6f64b1d | ||
|
|
de013d2f04 | ||
|
|
ed94cf9839 | ||
|
|
2fec7688b0 | ||
|
|
3c1834f0fc | ||
|
|
f6e78d3ecd | ||
|
|
dad7fce7a1 | ||
|
|
8058921f58 | ||
|
|
bb8e0e1047 | ||
|
|
5dcac6d2e3 | ||
|
|
552772d2a9 | ||
|
|
42611a787d | ||
|
|
743788d02f | ||
|
|
6028300366 | ||
|
|
70cb25766b | ||
|
|
36eede8f31 | ||
|
|
ec0dcdb685 | ||
|
|
2a1a821bb3 | ||
|
|
09c01e580a | ||
|
|
27902c9106 | ||
|
|
a8d328bba2 | ||
|
|
917d611883 | ||
|
|
94e0b644a7 | ||
|
|
10f8565e32 | ||
|
|
22bce41dd7 | ||
|
|
e35e73d2a3 | ||
|
|
f821f31a51 | ||
|
|
493af760ed | ||
|
|
3287bb9613 | ||
|
|
76606802d0 | ||
|
|
e99b32cacb | ||
|
|
87a6154de9 | ||
|
|
ed4c68e867 | ||
|
|
e2b68b4d9b | ||
|
|
686fca1863 | ||
|
|
0c1a5069d9 | ||
|
|
de88b1c71b | ||
|
|
4bba1058c6 | ||
|
|
49937f40a1 | ||
|
|
d55818a797 | ||
|
|
96897ee32e | ||
|
|
5522aaedf4 | ||
|
|
f3b7f4b14b | ||
|
|
01f74c75f5 | ||
|
|
24bcc3141d | ||
|
|
41108c98aa | ||
|
|
f5aa1d4406 | ||
|
|
ee4f503ec0 | ||
|
|
7095da9f9d | ||
|
|
7c656faa36 | ||
|
|
10515380e8 | ||
|
|
7301883e69 | ||
|
|
555f3782d4 | ||
|
|
7ecad86938 | ||
|
|
e496e9862c | ||
|
|
c8e989840f | ||
|
|
908067bdf9 | ||
|
|
2c7e61a6c7 | ||
|
|
ae824745a0 | ||
|
|
2b2c111af4 | ||
|
|
1bfa78896f | ||
|
|
e928c6f83c | ||
|
|
0e86da9d66 | ||
|
|
21dbbcfa56 | ||
|
|
0a512bf904 | ||
|
|
e6be1c1b79 | ||
|
|
a4eb03dfe1 | ||
|
|
fc1167fd34 | ||
|
|
561559277d | ||
|
|
68a3ccd45e | ||
|
|
fcfd4a6158 | ||
|
|
e621d2dfa2 | ||
|
|
a92ee5ba8d | ||
|
|
46c291835f | ||
|
|
4941fc15c0 | ||
|
|
48d7c6e6d1 | ||
|
|
73c46a3056 | ||
|
|
f2c82bf2b5 | ||
|
|
d3a3b26d16 | ||
|
|
c142bb0625 | ||
|
|
ec04a1846e | ||
|
|
0324fac616 | ||
|
|
4014087876 | ||
|
|
8a878a0d61 | ||
|
|
2b511aa2b9 | ||
|
|
6d8243d1b1 | ||
|
|
7ecaeb1a3d | ||
|
|
9ada8332d8 | ||
|
|
ca25f71a6e | ||
|
|
67790d3787 | ||
|
|
d301668811 | ||
|
|
6097ee3f9d | ||
|
|
43967feb2c | ||
|
|
8f4535f5eb | ||
|
|
dfe8a4f803 | ||
|
|
fe0d42e295 | ||
|
|
baf7e9aa2e | ||
|
|
60d03262d8 | ||
|
|
4bed503aa7 | ||
|
|
4518bf7d73 | ||
|
|
3d168fac14 | ||
|
|
746a703079 | ||
|
|
4aa5534f1d | ||
|
|
7c24855ba1 | ||
|
|
6222c38495 | ||
|
|
8709a47f6f | ||
|
|
1fb05038cd | ||
|
|
4f5d33988d | ||
|
|
75513ee975 | ||
|
|
b8fff9b750 | ||
|
|
d5f853c460 | ||
|
|
067dd5c7ef | ||
|
|
af1d05c4a4 | ||
|
|
c5ec01420f | ||
|
|
f25984e716 | ||
|
|
7babd82e6f | ||
|
|
d030874050 | ||
|
|
394a6dd5ea | ||
|
|
db6eb7d554 | ||
|
|
032304d503 | ||
|
|
f75c923627 | ||
|
|
bca8fa3f9c | ||
|
|
d713ea6389 | ||
|
|
f9fbe79e4f | ||
|
|
3cc0b4cdea | ||
|
|
eef9f622c0 | ||
|
|
889293e557 | ||
|
|
0c5b9f5d11 | ||
|
|
02af069d48 | ||
|
|
5e0056db8d | ||
|
|
4b5937f142 | ||
|
|
8d8d5e9746 | ||
|
|
5bdabe3e06 | ||
|
|
8a1db94d37 | ||
|
|
1911cba130 | ||
|
|
f4ed0b0ec6 | ||
|
|
6e42c527d7 | ||
|
|
f7d2339c6a | ||
|
|
cf5f373142 | ||
|
|
e09c675b70 | ||
|
|
6bd93f475c | ||
|
|
3f12bdf4c7 | ||
|
|
3aa7f6e298 | ||
|
|
4e28047eb4 | ||
|
|
f654b971d0 | ||
|
|
e742d1c9ae | ||
|
|
803b87e324 | ||
|
|
5107a7be16 | ||
|
|
1178291686 | ||
|
|
c8d1aa55b4 | ||
|
|
25a70ac5a8 | ||
|
|
6235a51d7c | ||
|
|
e1aec24e84 | ||
|
|
d9a6fb3ccf | ||
|
|
a47dd4570a | ||
|
|
8fa1b5a00b | ||
|
|
e537ab902e | ||
|
|
f0fb4a180a | ||
|
|
f957d895cd | ||
|
|
73c3a9e684 | ||
|
|
2ee1387f34 | ||
|
|
10cefb3337 | ||
|
|
7b369318dd | ||
|
|
cf2fb296f0 | ||
|
|
6cbd81f997 | ||
|
|
2025cf751f | ||
|
|
5a052103ae | ||
|
|
2ced5853b4 | ||
|
|
13edbb7d5e | ||
|
|
1643af4578 | ||
|
|
c7ac1e63bd | ||
|
|
fa3dd0ec20 | ||
|
|
34146c3f92 | ||
|
|
298ede17f5 | ||
|
|
d66ace8121 | ||
|
|
2e89722ef0 | ||
|
|
c8ad5f57d0 | ||
|
|
d2317943c0 | ||
|
|
198c9fc052 | ||
|
|
b3551f50a8 | ||
|
|
4ff360e621 | ||
|
|
87e8fa18cf | ||
|
|
4bd135c3c7 | ||
|
|
f69350e8bd | ||
|
|
5768d55a08 | ||
|
|
538264a8cd | ||
|
|
7f09f0e4ad | ||
|
|
e36084d7f2 | ||
|
|
bd18166a21 | ||
|
|
a6f2c38891 | ||
|
|
029a3f8f52 | ||
|
|
dc87aef335 | ||
|
|
d712806b39 | ||
|
|
2734724432 | ||
|
|
6176509076 | ||
|
|
1780efae07 | ||
|
|
922e8cbb2f | ||
|
|
eef0dd4fa4 | ||
|
|
f93f437f8b | ||
|
|
4e6d43e2ac | ||
|
|
922d29ee49 | ||
|
|
25475bdf42 | ||
|
|
09c413b1be | ||
|
|
8944c2f60d | ||
|
|
ff3fe4bf43 | ||
|
|
5fe2e19277 | ||
|
|
b8cf861aea | ||
|
|
6ca3576dbf | ||
|
|
7ea425db5e | ||
|
|
330ddb7adb | ||
|
|
d69b9fab4a | ||
|
|
4e02dc8751 | ||
|
|
0c8be405ce | ||
|
|
24677dc561 | ||
|
|
7e7c38755d | ||
|
|
229cd6d194 | ||
|
|
776e5d41d7 | ||
|
|
8d7e8a87b5 | ||
|
|
e24d8c936c | ||
|
|
39b6c4a273 | ||
|
|
da9b96fb12 | ||
|
|
7d855acd07 | ||
|
|
f961a2bf90 | ||
|
|
9f93af614f | ||
|
|
d529ba07d3 | ||
|
|
0fffb05d01 | ||
|
|
92b8409207 | ||
|
|
bc3134ba5a | ||
|
|
c7f55a182f | ||
|
|
5078be45b8 | ||
|
|
2418ea93fc | ||
|
|
13cac5de44 | ||
|
|
b6687925cc | ||
|
|
7ee51182bf | ||
|
|
ec3e5b4a75 | ||
|
|
0b5aac3d79 | ||
|
|
bea3180836 | ||
|
|
1ffd767977 | ||
|
|
a4e396fdd7 | ||
|
|
972d4fe0a5 | ||
|
|
148460c235 | ||
|
|
8c2f6790fe | ||
|
|
044272ea25 | ||
|
|
7d67dc8f1c | ||
|
|
71461d80bf | ||
|
|
9eac2788d7 | ||
|
|
6ff8202fa9 | ||
|
|
acf30de415 | ||
|
|
a766411306 | ||
|
|
cbcab61c65 | ||
|
|
c3d179f06e | ||
|
|
f42250ca9b | ||
|
|
7217903ce4 | ||
|
|
708abbf380 | ||
|
|
28dbec093b | ||
|
|
daf02f75b1 | ||
|
|
71b0460d11 | ||
|
|
ff62f4d425 | ||
|
|
53c523ab19 | ||
|
|
2285b9527b | ||
|
|
b4648ec4bd | ||
|
|
c6207db8fc | ||
|
|
1bd73c68f9 | ||
|
|
47016441f0 | ||
|
|
eeed384a51 | ||
|
|
cd5d6a5004 | ||
|
|
e4733002da | ||
|
|
15158ee0ca | ||
|
|
dc73c77d73 | ||
|
|
56529261db | ||
|
|
fcb1f7efd1 | ||
|
|
72b5e8b313 | ||
|
|
225964875c | ||
|
|
e580190074 | ||
|
|
8ef593904d | ||
|
|
51b9504720 | ||
|
|
e9d0e267c5 | ||
|
|
b028d4c254 |
12
.checkpatch.conf
Normal file
12
.checkpatch.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
--max-line-length=100
|
||||||
|
--strict
|
||||||
|
|
||||||
|
# Not Linux therefore don't expect a Linux tree
|
||||||
|
--no-tree
|
||||||
|
|
||||||
|
# Ignore the following
|
||||||
|
--ignore PREFER_KERNEL_TYPES
|
||||||
|
--ignore EXECUTE_PERMISSIONS
|
||||||
|
--ignore FILE_PATH_CHANGES
|
||||||
|
--ignore NEW_TYPEDEFS
|
||||||
|
--ignore SPDX_LICENSE_TAG
|
||||||
134
.clang-format
Normal file
134
.clang-format
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# Must be compatible with clang-format 14
|
||||||
|
---
|
||||||
|
AccessModifierOffset: "-4"
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveBitFields: AcrossComments
|
||||||
|
AlignConsecutiveMacros: AcrossComments
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: false
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakStringLiterals: false
|
||||||
|
ColumnLimit: "100"
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: "8"
|
||||||
|
ContinuationIndentWidth: "8"
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: false
|
||||||
|
# git grep -h '^#define [^[:space:]]*\(for_each\|iterate\)[^[:space:]]*(' \
|
||||||
|
# | sed "s,^#define \([^[:space:]]*\(for_each\|iterate\)[^[:space:]]*\)(.*$, - '\1'," \
|
||||||
|
# | LC_ALL=C sort -u
|
||||||
|
ForEachMacros:
|
||||||
|
- "dfi_cpu_iterate"
|
||||||
|
- "dfi_mem_chunk_iterate"
|
||||||
|
- "dfo_chunk_iterate"
|
||||||
|
- "for_each_rb_entry"
|
||||||
|
- "ns_range_for_each"
|
||||||
|
- "sd_cpu_item_enable_iterate"
|
||||||
|
- "sd_cpu_item_iterate"
|
||||||
|
- "sd_cpu_iterate"
|
||||||
|
- "sd_cpu_type_iterate"
|
||||||
|
- "sd_sys_item_enable_iterate"
|
||||||
|
- "sd_sys_item_iterate"
|
||||||
|
- "sd_sys_iterate"
|
||||||
|
- "table_col_iterate"
|
||||||
|
- "table_iterate_mark_keys"
|
||||||
|
- "util_list_iterate"
|
||||||
|
- "util_list_iterate_safe"
|
||||||
|
- "util_opt_iterate"
|
||||||
|
- "util_rec_iterate"
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
# Leave imports as is
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: .*
|
||||||
|
Priority: 1
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: "8"
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MaxEmptyLinesToKeep: "1"
|
||||||
|
NamespaceIndentation: Inner
|
||||||
|
PackConstructorInitializers: CurrentLine
|
||||||
|
PenaltyBreakAssignment: "10"
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: "30"
|
||||||
|
PenaltyBreakComment: "10"
|
||||||
|
PenaltyBreakFirstLessLess: "0"
|
||||||
|
PenaltyBreakString: "10"
|
||||||
|
PenaltyExcessCharacter: "100"
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: "60"
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: "1"
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
StatementMacros:
|
||||||
|
- "STATIC_ASSERT"
|
||||||
|
TabWidth: "8"
|
||||||
|
TypenameMacros:
|
||||||
|
- "STACK_OF"
|
||||||
|
UseTab: Always
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- "STRINGIFY"
|
||||||
5
.codespellrc
Normal file
5
.codespellrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[codespell]
|
||||||
|
ignore-words-list = parm,parms
|
||||||
|
skip = ''
|
||||||
|
count = ''
|
||||||
|
quiet-level = 3
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -9,6 +9,9 @@
|
|||||||
tags
|
tags
|
||||||
TAGS
|
TAGS
|
||||||
|
|
||||||
|
# clangd cache (https://clangd.llvm.org/design/indexing#backgroundindex)
|
||||||
|
.cache/
|
||||||
|
|
||||||
# Ignore coverage data
|
# Ignore coverage data
|
||||||
*.gcda
|
*.gcda
|
||||||
*.gcno
|
*.gcno
|
||||||
@@ -78,7 +81,6 @@ systemd/ttyrun-getty@.service
|
|||||||
tape390/tape390_crypt
|
tape390/tape390_crypt
|
||||||
tape390/tape390_display
|
tape390/tape390_display
|
||||||
tunedasd/src/tunedasd
|
tunedasd/src/tunedasd
|
||||||
vmconvert/vmconvert
|
|
||||||
vmcp/vmcp
|
vmcp/vmcp
|
||||||
vmur/vmur
|
vmur/vmur
|
||||||
zconf/chp/chchp
|
zconf/chp/chchp
|
||||||
@@ -95,6 +97,9 @@ zdev/src/chzdev_usage.c
|
|||||||
zdev/src/lszdev
|
zdev/src/lszdev
|
||||||
zdev/src/lszdev_usage.c
|
zdev/src/lszdev_usage.c
|
||||||
zdsfs/zdsfs
|
zdsfs/zdsfs
|
||||||
|
zdump/.check_dep_fuse
|
||||||
|
zdump/.check_dep_zgetdump
|
||||||
|
zdump/.detect_openssl.dep.c
|
||||||
zdump/zgetdump
|
zdump/zgetdump
|
||||||
zfcpdump/10-zfcpdump.install
|
zfcpdump/10-zfcpdump.install
|
||||||
zfcpdump/cpioinit
|
zfcpdump/cpioinit
|
||||||
@@ -107,6 +112,7 @@ ziomon/ziorep_traffic
|
|||||||
ziomon/ziorep_utilization
|
ziomon/ziorep_utilization
|
||||||
zipl/boot/*.bin
|
zipl/boot/*.bin
|
||||||
zipl/boot/*.exec
|
zipl/boot/*.exec
|
||||||
|
zipl/boot/.loaders
|
||||||
zipl/boot/data.h
|
zipl/boot/data.h
|
||||||
zipl/src/chreipl_helper.device-mapper
|
zipl/src/chreipl_helper.device-mapper
|
||||||
zdev/src/zdev_id
|
zdev/src/zdev_id
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Antoinette Kaschner
|
- Antoinette Kaschner
|
||||||
- Arnd Bergmann
|
- Arnd Bergmann
|
||||||
- Axel Wirbser
|
- Axel Wirbser
|
||||||
|
- Balint Reczey
|
||||||
- Benjamin Block
|
- Benjamin Block
|
||||||
- Brian C. Lane
|
- Brian C. Lane
|
||||||
- Carsten Otte
|
- Carsten Otte
|
||||||
@@ -20,6 +21,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Colin Walters
|
- Colin Walters
|
||||||
- Dan Horak
|
- Dan Horak
|
||||||
- Dan Horák
|
- Dan Horák
|
||||||
|
- Daniel S. Haischt
|
||||||
- Despina Papadopoulou
|
- Despina Papadopoulou
|
||||||
- Dimitri John Ledkov
|
- Dimitri John Ledkov
|
||||||
- Eberhard Pasch
|
- Eberhard Pasch
|
||||||
@@ -88,6 +90,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Mikhail Zaslonko
|
- Mikhail Zaslonko
|
||||||
- Nikita Dubrovskii
|
- Nikita Dubrovskii
|
||||||
- Niklas Schnelle
|
- Niklas Schnelle
|
||||||
|
- Nikolay Gueorguiev
|
||||||
- Peter Oberparleiter
|
- Peter Oberparleiter
|
||||||
- Peter Tiedemann
|
- Peter Tiedemann
|
||||||
- Philipp Kern
|
- Philipp Kern
|
||||||
|
|||||||
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,5 +1,135 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
* __v2.28.0 (2023-07-11)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.4
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- chzcrypt: Support for SE AP pass-through support
|
||||||
|
- genprotimg: Add support for non-s390x architectures
|
||||||
|
- lszcrypt: Support for SE AP pass-through support
|
||||||
|
- zdev: Add support for autoquiesce related sysfs attributes
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- ap_tools/ap-check: Handle missing 'matrix' and 'control_domains' attrs
|
||||||
|
- ap_tools/ap-check: Hold ap config file lock over get attributes
|
||||||
|
- s390-tools: Fix build for ppc64le
|
||||||
|
- zdev: Add missing label in the udev-rules
|
||||||
|
- zdev: Add proper value input for the ZDEV_SITE_ID key
|
||||||
|
- zdev: Use rename-file to avoid any symlinks created
|
||||||
|
- zipl/dump: fix ngdump dracut helper script
|
||||||
|
|
||||||
|
* __v2.27.0 (2023-05-30)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.3
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- s390-tools cross-compile and non-s390x support:
|
||||||
|
- `pkg-config` is now mandatory for the build process
|
||||||
|
- Add `PKG_CONFIG` Makefile variable to select pkg-config program;
|
||||||
|
default `pkg-config` or `$(CROSS_COMPILE)pkg-config` if
|
||||||
|
`CROSS_COMPILE` is set
|
||||||
|
- Rename Makefile variable `ARCH` to `HOST_ARCH`. `HOST_ARCH` is the
|
||||||
|
architecture that will run the produced (executable) objects
|
||||||
|
- Add the Makefile variable `BUILD_ARCH`. `BUILD_ARCH` is the
|
||||||
|
architecture of the build system. For each Makefile variable like
|
||||||
|
`CC`, `LINK`, `CPP`, ... there is a suffixed version of it - e.g.
|
||||||
|
`CC_FOR_BUILD`. This is useful for cross compiling, and this naming
|
||||||
|
convention is very similar to the Meson convention (see
|
||||||
|
https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine).
|
||||||
|
- Limit build targets for non-s390x architectures (pvattest)
|
||||||
|
- dasdfmt: Fall back to full format if space release fails
|
||||||
|
- dbginfo.sh: Add nstat for network and SNMP stats
|
||||||
|
- dbginfo.sh: Rework crypto data collection
|
||||||
|
- hyptop: Show thread util by default
|
||||||
|
- zipl: Add support for list-directed IPL dump from ECKD DASD
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- lszcrypt: Fix argument parsing
|
||||||
|
- zdev/dracut: Fix out-of-memory (OOM) situations in the kdump crashkernel environment
|
||||||
|
- ziomon/ziorep_config: Fix for SCSI devices of type disk without block dev
|
||||||
|
- pvextract-hdr: Fix parsing issues on little-endian systems
|
||||||
|
|
||||||
|
* __v2.26.0 (2023-02-14)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.2
|
||||||
|
|
||||||
|
Remove tools / libraries:
|
||||||
|
- Remove vmconvert and libvmdump in favor of vmdump file support in zdump
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- ipl_tools: Add support for list-directed IPL from ECKD DASD
|
||||||
|
- lszcrypt: Display hardware filtering support capability
|
||||||
|
- vmur: Remove option -c for dump file conversion (See zdump changes)
|
||||||
|
- zdev: Add zfcp ber_stop parameter handling
|
||||||
|
- zdump: Add vmdump dfi for vmdump format to elf format
|
||||||
|
- zkey: Support EP11 host library version
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- zipl: Move dump parmline processing and verification
|
||||||
|
- zipl/genprotimg: Various build improvements
|
||||||
|
|
||||||
|
* __v2.25.0 (2022-12-08)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.1
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- ap_tools: Use new mdevctl installation location
|
||||||
|
- lsdasd/tunedasd/zdev: Add support to handle copy pair relations presented by the DASD driver
|
||||||
|
- zdev: Add --shell command line switch to generate output suitable for shell environments
|
||||||
|
- zipl: Add List-Directed IPL from ECKD DASD to support secure boot
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- ipl_tools: Fix chreipl node for NVMes with CONFIG_NVME_MULTIPATH
|
||||||
|
- libdasd: Fix bug that prevented positive ioctl return codes
|
||||||
|
|
||||||
|
* __v2.24.0 (2022-11-09)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.0
|
||||||
|
|
||||||
|
Add new tools / libraries:
|
||||||
|
- Provide config files for checkpatch, codespell, and clang-format
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- dbginfo.sh: Collect log from various distro tools (YaST, DNF, Anaconda)
|
||||||
|
- dbginfo.sh: add Kubernetes data collection
|
||||||
|
- libutil: Introduce util_lockfile
|
||||||
|
- zdev: Add site-aware device configuration
|
||||||
|
- zdump: Add support to read Protected Virtualization dumps
|
||||||
|
- zipl/boot: Add secure boot trailer
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- ap_tools/ap-check: Reject start for control domains without usage
|
||||||
|
- cpumf/lshwc: Fix incremented counter output
|
||||||
|
- cpumf/pai: Fix core dump when summary flag set
|
||||||
|
- dbginfo.sh: Ensure compatibility with /bin/dash shell
|
||||||
|
- dbginfo.sh: Save dbginfo.sh version to dbginfo.log
|
||||||
|
- zipl/src/zipl_helper.device-mapper: Fix bug in error path
|
||||||
|
|
||||||
|
* __v2.23.0 (2022-08-18)__
|
||||||
|
|
||||||
|
For Linux kernel version: 5.19
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- Makefile: use common Make definition for DRACUTDIR
|
||||||
|
- Makefile: use common Make definition for UDEVDIR and UDEVRULESDIR
|
||||||
|
- cpacfstats: Add PAI and hotplug support
|
||||||
|
- cpumf/pai: Omit file write progress information
|
||||||
|
- dbginfo.sh: Get more details on lspci command
|
||||||
|
- dumpconf: Prevent running the service in containers
|
||||||
|
- libcpumf: Detect PMU named pai_ext
|
||||||
|
- pvattest: Improve error reporting and logging
|
||||||
|
- zdev: Add some --type ap examples to manpages
|
||||||
|
- zkey: Use default benchmarked Argon2i with LUKS2
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- dbginfo.sh: Fix accidental ftrace buffer shrinkage/free
|
||||||
|
- genprotimg: Fix BIO_reset() returncode handling
|
||||||
|
- libpv: Fix dependency checking
|
||||||
|
- pvattest: Fix dependency checking
|
||||||
|
- zipl: Fix segmentation fault when no parmline is provided
|
||||||
|
|
||||||
* __v2.22.0 (2022-06-20)__
|
* __v2.22.0 (2022-06-20)__
|
||||||
|
|
||||||
For Linux kernel version: 5.18
|
For Linux kernel version: 5.18
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ Coding guidelines for s390-tools
|
|||||||
For s390-tools the preferred language is C. We provide libraries, e.g.
|
For s390-tools the preferred language is C. We provide libraries, e.g.
|
||||||
[`libutil`](libutil) that should be used by all tools if possible.
|
[`libutil`](libutil) that should be used by all tools if possible.
|
||||||
|
|
||||||
The coding style is based on the Linux [kernel guidelines]. Therefore, use
|
The coding style is based on the Linux [kernel guidelines]. Therefore, use the
|
||||||
the [checkpatch] tool for verification before you submit a patch.
|
[checkpatch] tool for verification before you submit a patch. s390-tools
|
||||||
|
provides a CheckPatch configuration for this - see
|
||||||
|
[`.checkpatch.conf`](.checkpatch.conf).
|
||||||
|
|
||||||
[kernel guidelines]: https://www.kernel.org/doc/html/latest/process/coding-style.html
|
[kernel guidelines]: https://www.kernel.org/doc/html/latest/process/coding-style.html
|
||||||
[checkpatch]: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
|
[checkpatch]: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
|
||||||
@@ -17,6 +19,39 @@ This package started in 2001 and has a long "tradition" - therefore, older tools
|
|||||||
might not follow all recommendations. Note that when changing existing code,
|
might not follow all recommendations. Note that when changing existing code,
|
||||||
consistency could have priority over applying rules.
|
consistency could have priority over applying rules.
|
||||||
|
|
||||||
|
Automatic Code Formatting
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
> **NOTE:** clang-format is a helpful tool but please don't use it blindly!
|
||||||
|
|
||||||
|
s390-tools provides a ClangFormat (https://clang.llvm.org/docs/ClangFormat.html)
|
||||||
|
configuration file - see [`.clang-format`](.clang-format). It can be used to
|
||||||
|
format your C/C++ code automatically.
|
||||||
|
|
||||||
|
Clang-format can format a single file or multiple files at once. For example, to
|
||||||
|
format `main.c` in place, run the following command in a terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clang-format -i main.c
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to format only your current staged changes use the clang-format git
|
||||||
|
plugin:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clang-format --staged
|
||||||
|
```
|
||||||
|
|
||||||
|
See also `git clang-format -h`.
|
||||||
|
|
||||||
|
Automatic Editor Configuration
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
s390-tools provides a EditorConfig (https://editorconfig.org/) configuration
|
||||||
|
file - see [`.editorconfig`](.editorconfig). EditorConfig defines coding style
|
||||||
|
rules (such as indentation size, use of tabs, etc.) and is supported by most
|
||||||
|
common editors natively or via plugins.
|
||||||
|
|
||||||
Standard abbreviations
|
Standard abbreviations
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|||||||
18
Makefile
18
Makefile
@@ -1,5 +1,3 @@
|
|||||||
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
|
|
||||||
|
|
||||||
# Include common definitions
|
# Include common definitions
|
||||||
include common.mak
|
include common.mak
|
||||||
|
|
||||||
@@ -8,15 +6,21 @@ include common.mak
|
|||||||
# LIBS: Libraries that can have a dependency to base libraries
|
# LIBS: Libraries that can have a dependency to base libraries
|
||||||
# TOOLS: Tools that can have a dependency to base libraries or libraries
|
# TOOLS: Tools that can have a dependency to base libraries or libraries
|
||||||
#
|
#
|
||||||
|
ifeq ($(HOST_ARCH),s390x)
|
||||||
BASELIB_DIRS = libutil libseckey
|
BASELIB_DIRS = libutil libseckey
|
||||||
LIB_DIRS = libvtoc libzds libdasd libvmdump libccw libvmcp libekmfweb \
|
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
|
||||||
libkmipclient libcpumf libap libpv
|
libkmipclient libcpumf libap libpv
|
||||||
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||||
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
|
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
|
||||||
|
else
|
||||||
|
BASELIB_DIRS =
|
||||||
|
LIB_DIRS = libpv
|
||||||
|
TOOL_DIRS = genprotimg pvattest
|
||||||
|
endif
|
||||||
|
|
||||||
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
||||||
|
|
||||||
@@ -49,15 +53,15 @@ endif
|
|||||||
|
|
||||||
$(TOOL_DIRS): $(LIB_DIRS)
|
$(TOOL_DIRS): $(LIB_DIRS)
|
||||||
$(foreach goal,$(MAKECMDGOALS), \
|
$(foreach goal,$(MAKECMDGOALS), \
|
||||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||||
.PHONY: $(TOOL_DIRS)
|
.PHONY: $(TOOL_DIRS)
|
||||||
|
|
||||||
$(LIB_DIRS): $(BASELIB_DIRS)
|
$(LIB_DIRS): $(BASELIB_DIRS)
|
||||||
$(foreach goal,$(MAKECMDGOALS), \
|
$(foreach goal,$(MAKECMDGOALS), \
|
||||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||||
.PHONY: $(LIB_DIRS)
|
.PHONY: $(LIB_DIRS)
|
||||||
|
|
||||||
$(BASELIB_DIRS):
|
$(BASELIB_DIRS):
|
||||||
$(foreach goal,$(MAKECMDGOALS), \
|
$(foreach goal,$(MAKECMDGOALS), \
|
||||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||||
.PHONY: $(BASELIB_DIRS)
|
.PHONY: $(BASELIB_DIRS)
|
||||||
|
|||||||
48
README.md
48
README.md
@@ -60,6 +60,7 @@ Package contents
|
|||||||
|
|
||||||
* zgetdump:
|
* zgetdump:
|
||||||
Retrieve system dumps from either tapes, DASDs, SCSIs or NVMes.
|
Retrieve system dumps from either tapes, DASDs, SCSIs or NVMes.
|
||||||
|
Decrypt Protected Virtualization (PV) dumps from IBM Secure Execution guests.
|
||||||
|
|
||||||
* qetharp:
|
* qetharp:
|
||||||
Read and flush the ARP cache on OSA Express network cards.
|
Read and flush the ARP cache on OSA Express network cards.
|
||||||
@@ -97,11 +98,6 @@ Package contents
|
|||||||
* tunedasd:
|
* tunedasd:
|
||||||
Adjust tunable parameters on DASD devices.
|
Adjust tunable parameters on DASD devices.
|
||||||
|
|
||||||
* vmconvert:
|
|
||||||
Convert system dumps created by the z/VM VMDUMP command into dumps with
|
|
||||||
LKCD format. These LKCD dumps can then be analyzed with the dump analysis
|
|
||||||
tool lcrash.
|
|
||||||
|
|
||||||
* vmcp:
|
* vmcp:
|
||||||
Send commands from Linux as a z/VM guest to the z/VM control program (CP).
|
Send commands from Linux as a z/VM guest to the z/VM control program (CP).
|
||||||
Call vmcp with the CP command as an argument. The response of z/VM is
|
Call vmcp with the CP command as an argument. The response of z/VM is
|
||||||
@@ -306,20 +302,19 @@ build options:
|
|||||||
| | | hsavmcore |
|
| | | hsavmcore |
|
||||||
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
|
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
|
||||||
| ncurses | `HAVE_NCURSES` | hyptop |
|
| ncurses | `HAVE_NCURSES` | hyptop |
|
||||||
| pfm | `HAVE_PFM` | cpacfstats |
|
|
||||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||||
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
||||||
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb, |
|
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb, |
|
||||||
| | | libkmipclient, pvattest |
|
| | | libkmipclient, pvattest, zgetdump |
|
||||||
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb, |
|
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb, |
|
||||||
| | | libkmipclient |
|
| | | libkmipclient |
|
||||||
| glib2 | `HAVE_GLIB2` | genprotimg, pvattest |
|
| glib2 | `HAVE_GLIB2` | genprotimg, pvattest, zgetdump |
|
||||||
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb, libkmipclient,|
|
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb, libkmipclient,|
|
||||||
| | | pvattest |
|
| | | pvattest |
|
||||||
| libxml2 | `HAVE_LIBXML2` | libkmipclient |
|
| libxml2 | `HAVE_LIBXML2` | libkmipclient |
|
||||||
| systemd | `HAVE_SYSTEMD` | hsavmcore |
|
| systemd | `HAVE_SYSTEMD` | hsavmcore |
|
||||||
| liblockfile | `HAVE_LOCKFILE` | ap-check |
|
| libudev | `HAVE_LIBUDEV` | cpacfstatsd |
|
||||||
|
|
||||||
This table lists additional build or install options:
|
This table lists additional build or install options:
|
||||||
|
|
||||||
@@ -330,8 +325,8 @@ This table lists additional build or install options:
|
|||||||
| initramfs-tools | `HAVE_INITRAMFS` | zdev, zipl |
|
| initramfs-tools | `HAVE_INITRAMFS` | zdev, zipl |
|
||||||
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
|
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
|
||||||
|
|
||||||
The s390-tools build process uses "pkg-config" if available and hard-coded
|
The s390-tools build process uses "pkg-config" and therefore it must be
|
||||||
compiler and linker options otherwise.
|
available.
|
||||||
|
|
||||||
Build and runtime requirements for specific tools
|
Build and runtime requirements for specific tools
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
@@ -376,6 +371,13 @@ the different tools are provided:
|
|||||||
- Packages: blktrace, multipath-tools, sg3-utils
|
- Packages: blktrace, multipath-tools, sg3-utils
|
||||||
- Tools: rsync, tar, lsscsi
|
- Tools: rsync, tar, lsscsi
|
||||||
|
|
||||||
|
* zgetdump
|
||||||
|
For building zgetdump you need OpenSSL version 1.1.0 or newer
|
||||||
|
installed (openssl-devel.rpm). Also required is glib2
|
||||||
|
(glib2-devel.rpm) and zlib (zlib-devel.rpm).
|
||||||
|
Tip: you may skip the zgetdump build by adding
|
||||||
|
`HAVE_OPENSSL=0`, `HAVE_GLIB2=0`, or `HAVE_ZLIB=0`.
|
||||||
|
|
||||||
* cmsfs-fuse/zdsfs/hmcdrvfs/zgetdump:
|
* cmsfs-fuse/zdsfs/hmcdrvfs/zgetdump:
|
||||||
The tools cmsfs-fuse, zdsfs, hmcdrvfs, and zgetdump depend on FUSE.
|
The tools cmsfs-fuse, zdsfs, hmcdrvfs, and zgetdump depend on FUSE.
|
||||||
FUSE is provided by installing the fuse3 and libfuse3 packages and by a
|
FUSE is provided by installing the fuse3 and libfuse3 packages and by a
|
||||||
@@ -403,14 +405,13 @@ the different tools are provided:
|
|||||||
As of s390-tools-1.13.0, the minimum required kernel level is 2.6.38.
|
As of s390-tools-1.13.0, the minimum required kernel level is 2.6.38.
|
||||||
|
|
||||||
* cpacfstats:
|
* cpacfstats:
|
||||||
For building the cpacfstats tools you need libpfm version 4 or
|
For building the cpacfstats tools you need libudev installed
|
||||||
newer installed (libpfm-devel.rpm). Tip: you may skip the cpacfstats
|
(systemd-devel.rpm). Tip: you may skip the cpacfstats build by
|
||||||
build by adding `HAVE_PFN=0` to the make invocation. To run the
|
adding `HAVE_LIBUDEV=0` to the make invocation. To run the
|
||||||
cpacfstats daemon the kernel needs to have performance
|
cpacfstats daemon the kernel needs to have performance events
|
||||||
events enabled (check for `CONFIG_PERF_EVENTS=y`) and you need libpfm
|
enabled (check for `CONFIG_PERF_EVENTS=y`). A new group 'cpacfstats'
|
||||||
version 4 or newer installed. A new group 'cpacfstats' needs to be
|
needs to be created and all users intending to use the tool should
|
||||||
created and all users intending to use the tool should be added to
|
be added to this group.
|
||||||
this group.
|
|
||||||
|
|
||||||
* zdev:
|
* zdev:
|
||||||
Depending on the boot loader and initial RAM-disk mechanism used by a
|
Depending on the boot loader and initial RAM-disk mechanism used by a
|
||||||
@@ -506,8 +507,7 @@ the different tools are provided:
|
|||||||
GNU awk for the build process.
|
GNU awk for the build process.
|
||||||
|
|
||||||
* ap-check:
|
* ap-check:
|
||||||
For building the ap-check mdevctl callout utility you need liblockfile
|
For building the ap-check mdevctl callout utility you need json-c version
|
||||||
version 1.14 or newer installed (liblockfile-devel.rpm). Also required is
|
0.13 or newer (json-c-devel.rpm).
|
||||||
json-c version 0.13 or newer (json-c-devel.rpm).
|
Tip: you may skip ap-check build by adding `HAVE_JSONC=0` to the make
|
||||||
Tip: you may skip ap-check build by adding `HAVE_LOCKFILE=0` or `HAVE_JSONC=0`
|
invocation.
|
||||||
to the make invocation.
|
|
||||||
|
|||||||
@@ -1,27 +1,23 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
MDEVCTL_DIR = /etc/mdevctl.d/
|
MDEVCTL_DIR = /usr/lib/mdevctl/
|
||||||
MDEVCTL_SCRIPTS = /etc/mdevctl.d/scripts.d/
|
MDEVCTL_SCRIPTS = /usr/lib/mdevctl/scripts.d/
|
||||||
MDEVCTL_CALLOUTS = /etc/mdevctl.d/scripts.d/callouts/
|
MDEVCTL_CALLOUTS = /usr/lib/mdevctl/scripts.d/callouts/
|
||||||
|
MDEVCTL_DEP_DIR = /etc/mdevctl.d/
|
||||||
|
MDEVCTL_DEP_SCRIPTS = /etc/mdevctl.d/scripts.d/
|
||||||
|
MDEVCTL_DEP_CALLOUTS = /etc/mdevctl.d/scripts.d/callouts/
|
||||||
|
|
||||||
libs = $(rootdir)/libap/libap.a \
|
libs = $(rootdir)/libap/libap.a \
|
||||||
$(rootdir)/libutil/libutil.a
|
$(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
ifeq (${HAVE_LOCKFILE},0)
|
ifeq (${HAVE_JSONC},0)
|
||||||
all:
|
|
||||||
$(SKIP) HAVE_LOCKFILE=0
|
|
||||||
|
|
||||||
install:
|
|
||||||
$(SKIP) HAVE_LOCKFILE=0
|
|
||||||
|
|
||||||
else ifeq (${HAVE_JSONC},0)
|
|
||||||
all:
|
all:
|
||||||
$(SKIP) HAVE_JSONC=0
|
$(SKIP) HAVE_JSONC=0
|
||||||
|
|
||||||
install:
|
install:
|
||||||
$(SKIP) HAVE_JSONC=0
|
$(SKIP) HAVE_JSONC=0
|
||||||
else
|
else
|
||||||
LDLIBS += -llockfile -ljson-c
|
LDLIBS += -ljson-c
|
||||||
|
|
||||||
all: ap-check
|
all: ap-check
|
||||||
|
|
||||||
@@ -30,15 +26,26 @@ ap-check: ap-check.o $(libs)
|
|||||||
install: all
|
install: all
|
||||||
@if [ ! -d $(DESTDIR)$(MDEVCTL_CALLOUTS) ]; then \
|
@if [ ! -d $(DESTDIR)$(MDEVCTL_CALLOUTS) ]; then \
|
||||||
mkdir -p $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
mkdir -p $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||||
chmod 755 $(DESTDIR)$(MDEVCTL_DIR); \
|
chmod 755 $(DESTDIR)$(MDEVCTL_DIR); \
|
||||||
chmod 755 $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
chmod 755 $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
||||||
chmod 755 $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
chmod 755 $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||||
fi; \
|
fi; \
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check \
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check \
|
||||||
$(DESTDIR)$(MDEVCTL_CALLOUTS)
|
$(DESTDIR)$(MDEVCTL_CALLOUTS)
|
||||||
|
@if [ ! -d $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS) ]; then \
|
||||||
|
mkdir -p $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||||
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \
|
||||||
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
|
||||||
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||||
|
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_DIR); \
|
||||||
|
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
|
||||||
|
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||||
|
fi; \
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check.sh \
|
||||||
|
$(DESTDIR)$(MDEVCTL_DEP_CALLOUTS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ static void ap_check_cleanup(struct ap_check_anchor *anc)
|
|||||||
if (anc->dev)
|
if (anc->dev)
|
||||||
vfio_ap_device_free(anc->dev);
|
vfio_ap_device_free(anc->dev);
|
||||||
if (anc->cleanup_lock)
|
if (anc->cleanup_lock)
|
||||||
ap_release_lock();
|
ap_release_lock_callout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -434,14 +434,23 @@ static int check_other_mdev_sysfs_cb(const char *path, const char *filename,
|
|||||||
strcasecmp(filename, cbdata->uuid) == 0)
|
strcasecmp(filename, cbdata->uuid) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev2 = vfio_ap_device_new();
|
/*
|
||||||
|
* Read the 'matrix' attribute to get the list of queues for the active
|
||||||
|
* device. If the sysfs attribute is unreadable, assume the device is
|
||||||
|
* being destroyed and skip it.
|
||||||
|
*/
|
||||||
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
|
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
|
||||||
f = fopen(matrix_path, "r");
|
f = fopen(matrix_path, "r");
|
||||||
|
free(matrix_path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev2 = vfio_ap_device_new();
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_matrix(dev2, buf);
|
vfio_ap_parse_matrix(dev2, buf);
|
||||||
vfio_ap_sort_matrix_results(dev2);
|
vfio_ap_sort_matrix_results(dev2);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(matrix_path);
|
|
||||||
|
|
||||||
/* Look for conflicts between target device and this device */
|
/* Look for conflicts between target device and this device */
|
||||||
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
|
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
|
||||||
@@ -685,6 +694,14 @@ static int ap_check_handle_start(struct ap_check_anchor *anc)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure device with control domains also has usage domains */
|
||||||
|
if (util_list_is_empty(anc->dev->domains) &&
|
||||||
|
!util_list_is_empty(anc->dev->controls)) {
|
||||||
|
fprintf(stderr, "At least one usage domain must be specified\n");
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check against all other active vfio-ap devices */
|
/* Check against all other active vfio-ap devices */
|
||||||
rc = check_other_mdevs_sysfs(anc);
|
rc = check_other_mdevs_sysfs(anc);
|
||||||
/* Check against the system sysfs values for apmask/aqmask */
|
/* Check against the system sysfs values for apmask/aqmask */
|
||||||
@@ -767,7 +784,7 @@ out:
|
|||||||
*/
|
*/
|
||||||
static int ap_check_handle_post(void)
|
static int ap_check_handle_post(void)
|
||||||
{
|
{
|
||||||
return ap_release_lock();
|
return ap_release_lock_callout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the specified device, print the attributes to stdout in JSON format */
|
/* For the specified device, print the attributes to stdout in JSON format */
|
||||||
@@ -779,21 +796,39 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
|||||||
char buf[80];
|
char buf[80];
|
||||||
char *path;
|
char *path;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ap_get_lock_callout();
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
anc->cleanup_lock = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the 'matrix' and 'control_domains' attributes to get the
|
||||||
|
* current attributes of the active device. If either of these sysfs
|
||||||
|
* attributes is unreadable, assume the device is being destroyed
|
||||||
|
* and return nothing.
|
||||||
|
*/
|
||||||
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
|
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
|
||||||
f = fopen(path, "r");
|
f = fopen(path, "r");
|
||||||
|
free(path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_matrix(dev, buf);
|
vfio_ap_parse_matrix(dev, buf);
|
||||||
vfio_ap_sort_matrix_results(dev);
|
vfio_ap_sort_matrix_results(dev);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(path);
|
|
||||||
|
|
||||||
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
|
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
|
||||||
f = fopen(path, "r");
|
f = fopen(path, "r");
|
||||||
|
free(path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_control(dev, buf);
|
vfio_ap_parse_control(dev, buf);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(path);
|
|
||||||
|
|
||||||
printf("[{");
|
printf("[{");
|
||||||
|
|
||||||
|
|||||||
15
ap_tools/ap-check.sh
Normal file
15
ap_tools/ap-check.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# ap-check.sh - Wrapper script for 'ap-check' binary
|
||||||
|
#
|
||||||
|
# mdevctl has deprecated the /etc/mdevctl.d/scripts.d/callouts/ location in
|
||||||
|
# newer releases. This wrapper ensures that mdevctl 1.2.0 and older can
|
||||||
|
# still access 'ap-check' for now, and will be removed at a later time.
|
||||||
|
#
|
||||||
|
# Copyright 2022 IBM Corp.
|
||||||
|
#
|
||||||
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
#
|
||||||
|
|
||||||
|
[ -e /usr/lib/mdevctl/scripts.d/callouts/ap-check ] && /usr/lib/mdevctl/scripts.d/callouts/ap-check "$@"
|
||||||
@@ -27,11 +27,7 @@ ENABLE_DOC = 0
|
|||||||
|
|
||||||
# https://www.gnu.org/software/make/manual/make.html#Directory-Variables
|
# https://www.gnu.org/software/make/manual/make.html#Directory-Variables
|
||||||
CHREIPLZFCPMPDIR = $(USRLIBDIR)/chreipl-fcp-mpath
|
CHREIPLZFCPMPDIR = $(USRLIBDIR)/chreipl-fcp-mpath
|
||||||
UDEVDIR = $(USRLIBDIR)/udev
|
|
||||||
UDEVRULESDIR = $(UDEVDIR)/rules.d
|
|
||||||
UDEVRUNDIR = /run/udev
|
UDEVRUNDIR = /run/udev
|
||||||
DRACUTDIR = $(USRLIBDIR)/dracut
|
|
||||||
DRACUTCONFDIR = $(DRACUTDIR)/dracut.conf.d
|
|
||||||
DEBUGOUTDIR = $(UDEVRUNDIR)
|
DEBUGOUTDIR = $(UDEVRUNDIR)
|
||||||
|
|
||||||
INSTALL_EXEC = $(INSTALL) -g $(GROUP) -o $(OWNER) --preserve-timestamps
|
INSTALL_EXEC = $(INSTALL) -g $(GROUP) -o $(OWNER) --preserve-timestamps
|
||||||
@@ -78,7 +74,7 @@ ALL_PANDOCFLAGS = --preserve-tabs --tab-stop=8 --strip-comments \
|
|||||||
-M date="$(shell date +'%Y-%m-%d')" \
|
-M date="$(shell date +'%Y-%m-%d')" \
|
||||||
$(PANDOCFLAGS)
|
$(PANDOCFLAGS)
|
||||||
|
|
||||||
$(eval $(call cmd_define, PANDOC," PANDOC ",pandoc))
|
$(eval $(call cmd_define_and_export, PANDOC," PANDOC ",pandoc))
|
||||||
|
|
||||||
%.html : ALL_PANDOCFLAGS += -t html
|
%.html : ALL_PANDOCFLAGS += -t html
|
||||||
%.html : %.md
|
%.html : %.md
|
||||||
|
|||||||
@@ -22,13 +22,8 @@ check_dep:
|
|||||||
|
|
||||||
all: check_dep cmsfs-fuse
|
all: check_dep cmsfs-fuse
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
|
||||||
else
|
|
||||||
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
|
||||||
FUSE_LDLIBS = -lfuse3
|
|
||||||
endif
|
|
||||||
ALL_CFLAGS += -DHAVE_SETXATTR $(FUSE_CFLAGS)
|
ALL_CFLAGS += -DHAVE_SETXATTR $(FUSE_CFLAGS)
|
||||||
LDLIBS += $(FUSE_LDLIBS) -lm
|
LDLIBS += $(FUSE_LDLIBS) -lm
|
||||||
|
|
||||||
|
|||||||
163
common.mak
163
common.mak
@@ -1,25 +1,47 @@
|
|||||||
ifndef $(COMMON_INCLUDED)
|
COMMON_INCLUDED ?= false
|
||||||
COMMON_INCLUDED = true
|
V ?= 0
|
||||||
|
W ?= 0
|
||||||
|
G ?= 0
|
||||||
|
C ?= 0
|
||||||
|
D ?= 0
|
||||||
|
ASAN ?= 0
|
||||||
|
ENABLE_WERROR ?= 0
|
||||||
|
OPT_FLAGS ?=
|
||||||
|
MAKECMDGOALS ?=
|
||||||
|
|
||||||
|
ifeq ($(COMMON_INCLUDED),false)
|
||||||
|
COMMON_INCLUDED := true
|
||||||
|
|
||||||
|
# 'BUILD_ARCH' is the architecture of the machine where the build takes place
|
||||||
|
BUILD_ARCH := $(shell uname -m | sed -e 's/i.86/i386/' -e 's/sun4u/sparc64/' -e 's/arm.*/arm/' -e 's/sa110/arm/')
|
||||||
|
# 'HOST_ARCH' is the architecture of the machine that will run the compiled output
|
||||||
|
HOST_ARCH ?= $(BUILD_ARCH)
|
||||||
|
|
||||||
|
# The `*clean` targets are mutually exclusive to all other targets
|
||||||
|
ifneq ($(filter %clean,$(MAKECMDGOALS)),)
|
||||||
|
ifneq ($(MAKECMDGOALS),$(filter %clean,$(MAKECMDGOALS)))
|
||||||
|
$(error The *clean targets are mutually exclusive to all other targets)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# Global definitions
|
# Global definitions
|
||||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
RELEASE = 22
|
RELEASE = 28
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
export S390_TOOLS_RELEASE
|
export S390_TOOLS_RELEASE
|
||||||
|
|
||||||
reldir = $(subst $(shell cd -P $(dir $(filter %common.mak,$(MAKEFILE_LIST))); \
|
reldir = $(subst $(realpath $(dir $(filter %common.mak,$(MAKEFILE_LIST))))/,,$(CURDIR))
|
||||||
pwd)/,,$(CURDIR))
|
|
||||||
rootdir= $(dir $(filter %common.mak,$(MAKEFILE_LIST)))
|
rootdir= $(dir $(filter %common.mak,$(MAKEFILE_LIST)))
|
||||||
export S390_TEST_LIB_PATH=$(rootdir)/s390-tools-testsuite/lib
|
export S390_TEST_LIB_PATH=$(rootdir)/s390-tools-testsuite/lib
|
||||||
|
|
||||||
#
|
#
|
||||||
# For cross compiles specify CROSS_COMPILE= on the commandline:
|
# For cross compiles specify HOST_ARCH= and CROSS_COMPILE= on the commandline:
|
||||||
#
|
#
|
||||||
# $ make CROSS_COMPILE="s390x-5.1.0-"
|
# $ make HOST_ARCH=s390x CROSS_COMPILE="s390x-linux-gnu-"
|
||||||
#
|
#
|
||||||
|
|
||||||
CROSS_COMPILE =
|
CROSS_COMPILE =
|
||||||
@@ -29,8 +51,10 @@ CROSS_COMPILE =
|
|||||||
#
|
#
|
||||||
# $ make CC=gcc-4.8
|
# $ make CC=gcc-4.8
|
||||||
#
|
#
|
||||||
# The "cmd_define" macro wraps the command definition so that the commands
|
# The "cmd_define_and_export" macro wraps the command definition so that
|
||||||
# can be user supplied and are still pretty-printed for the build process.
|
# the commands can be user supplied and are still pretty-printed for the
|
||||||
|
# build process. In addition, the command variable gets exported so it
|
||||||
|
# can be used by sub-makes.
|
||||||
#
|
#
|
||||||
# The macro is called with the following parameters:
|
# The macro is called with the following parameters:
|
||||||
#
|
#
|
||||||
@@ -40,13 +64,14 @@ CROSS_COMPILE =
|
|||||||
#
|
#
|
||||||
# The Example below...
|
# The Example below...
|
||||||
#
|
#
|
||||||
# $(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
# $(eval $(call cmd_define_and_export, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||||
#
|
#
|
||||||
# ... produces the following code:
|
# ... produces the following code:
|
||||||
#
|
#
|
||||||
# CC = $(CROSS_COMPILE)gcc
|
# CC = $(CROSS_COMPILE)gcc
|
||||||
# CC_SILENT := $(CC)
|
# CC_SILENT := $(CC)
|
||||||
# override CC = $(call echocmd," CC ",/$@)$(CC_SILENT)
|
# override CC = $(call echocmd," CC ",/$@)$(CC_SILENT)
|
||||||
|
# export CC
|
||||||
#
|
#
|
||||||
# The "strip" make function is used for the first parameter to allow blanks,
|
# The "strip" make function is used for the first parameter to allow blanks,
|
||||||
# which improves readability.
|
# which improves readability.
|
||||||
@@ -58,21 +83,47 @@ define cmd_define
|
|||||||
override $(strip $(1)) = $$(call echocmd,$(2),/$$@)$$($(strip $(1))_SILENT)
|
override $(strip $(1)) = $$(call echocmd,$(2),/$$@)$$($(strip $(1))_SILENT)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as))
|
define cmd_define_and_export
|
||||||
$(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
$(call cmd_define,$(1),$(2),$(3))
|
||||||
$(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc))
|
export $(strip $(1))
|
||||||
$(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++))
|
endef
|
||||||
$(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E))
|
|
||||||
$(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar))
|
define define_toolchain_variables
|
||||||
$(eval $(call cmd_define, NM," NM ",$(CROSS_COMPILE)nm))
|
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
|
||||||
$(eval $(call cmd_define, STRIP," STRIP ",$(CROSS_COMPILE)strip))
|
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
|
||||||
$(eval $(call cmd_define,OBJCOPY," OBJCOPY ",$(CROSS_COMPILE)objcopy))
|
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
|
||||||
$(eval $(call cmd_define,OBJDUMP," OBJDUMP ",$(CROSS_COMPILE)objdump))
|
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
|
||||||
|
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
|
||||||
|
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
|
||||||
|
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
|
||||||
|
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
|
||||||
|
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
|
||||||
|
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
|
||||||
|
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
|
||||||
|
$(eval PKG_CONFIG$(1) = pkg-config)
|
||||||
|
$(eval export PKG_CONFIG$(1))
|
||||||
|
endef
|
||||||
|
|
||||||
|
# If the host architecture is not the same as the build architecture
|
||||||
|
# 'CROSS_COMPILE=...' is always required (except for the '*clean' targets).
|
||||||
|
ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
||||||
|
ifeq ($(CROSS_COMPILE),)
|
||||||
|
# `make clean` and similar must always work!
|
||||||
|
ifeq ($(filter %clean,$(MAKECMDGOALS)),)
|
||||||
|
$(error Please specify CROSS_COMPILE=... and try it again!)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(call define_toolchain_variables,_FOR_BUILD,)
|
||||||
|
$(call define_toolchain_variables,,$(CROSS_COMPILE))
|
||||||
|
|
||||||
$(eval $(call cmd_define,RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
$(eval $(call cmd_define,RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
||||||
$(eval $(call cmd_define, CAT," CAT ",cat))
|
$(eval $(call cmd_define, CAT," CAT ",cat))
|
||||||
$(eval $(call cmd_define, SED," SED ",sed))
|
$(eval $(call cmd_define, SED," SED ",sed))
|
||||||
$(eval $(call cmd_define, GZIP," GZIP ",gzip))
|
$(eval $(call cmd_define, GZIP," GZIP ",gzip))
|
||||||
$(eval $(call cmd_define, MV," MV ",mv))
|
$(eval $(call cmd_define, MV," MV ",mv))
|
||||||
|
$(eval $(call cmd_define, PERLC," PERLC ",perl -c))
|
||||||
|
|
||||||
CHECK = sparse
|
CHECK = sparse
|
||||||
CHECK_SILENT := $(CHECK)
|
CHECK_SILENT := $(CHECK)
|
||||||
@@ -81,8 +132,6 @@ CHECKTOOL = $(call echocmd," CHECK ",/$@)$(CHECK_SILENT)
|
|||||||
SKIP = echo " SKIP $(call reldir) due to"
|
SKIP = echo " SKIP $(call reldir) due to"
|
||||||
|
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
LINK = $(CC)
|
|
||||||
LINKXX = $(CXX)
|
|
||||||
CP = cp
|
CP = cp
|
||||||
ifneq ("${V}","1")
|
ifneq ("${V}","1")
|
||||||
MAKEFLAGS += --quiet
|
MAKEFLAGS += --quiet
|
||||||
@@ -91,7 +140,7 @@ ifneq ("${V}","1")
|
|||||||
else
|
else
|
||||||
echocmd=
|
echocmd=
|
||||||
endif
|
endif
|
||||||
DEFAULT_CFLAGS = -g -rdynamic -fstack-protector-all -W -Wall -Wformat-security
|
DEFAULT_CFLAGS = -g -fstack-protector-all -W -Wall -Wformat-security
|
||||||
ifeq ("${W}","1")
|
ifeq ("${W}","1")
|
||||||
DEFAULT_CFLAGS += -Wextra -Wshadow -Wundef -Wuninitialized -Wdouble-promotion -Wconversion
|
DEFAULT_CFLAGS += -Wextra -Wshadow -Wundef -Wuninitialized -Wdouble-promotion -Wconversion
|
||||||
endif
|
endif
|
||||||
@@ -101,6 +150,10 @@ else
|
|||||||
DEFAULT_CFLAGS += -O3
|
DEFAULT_CFLAGS += -O3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("${ENABLE_WERROR}", "1")
|
||||||
|
DEFAULT_CFLAGS += -Werror
|
||||||
|
endif
|
||||||
|
|
||||||
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
||||||
DEFAULT_LDFLAGS = -rdynamic
|
DEFAULT_LDFLAGS = -rdynamic
|
||||||
|
|
||||||
@@ -109,6 +162,11 @@ ifeq ("${ASAN}","1")
|
|||||||
DEFAULT_LDFLAGS += -fsanitize=address
|
DEFAULT_LDFLAGS += -fsanitize=address
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
DEFAULT_PERLCFLAGS =
|
||||||
|
ifeq ("${W}","1")
|
||||||
|
DEFAULT_PERLCFLAGS += -w
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for header prerequisite
|
# Check for header prerequisite
|
||||||
#
|
#
|
||||||
@@ -120,7 +178,7 @@ endif
|
|||||||
define check_header_prereq
|
define check_header_prereq
|
||||||
$(shell printf "#include <%s>\n int main(void) {return 0;}\n" $1 | \
|
$(shell printf "#include <%s>\n int main(void) {return 0;}\n" $1 | \
|
||||||
( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) \
|
( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) \
|
||||||
$2 -o /dev/null -xc - ) >/dev/null 2>&1 && echo -n yes)
|
$2 -o /dev/null -x c - ) >/dev/null 2>&1 && echo -n yes)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -133,7 +191,7 @@ endef
|
|||||||
# $5: Additional compiler & linker options (optional)
|
# $5: Additional compiler & linker options (optional)
|
||||||
#
|
#
|
||||||
check_dep=\
|
check_dep=\
|
||||||
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -xc - ) > /dev/null 2>&1; \
|
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -x c - ) > /dev/null 2>&1; \
|
||||||
if [ $$? != 0 ]; \
|
if [ $$? != 0 ]; \
|
||||||
then \
|
then \
|
||||||
printf " REQCHK %s (%s)\n" $1 $2; \
|
printf " REQCHK %s (%s)\n" $1 $2; \
|
||||||
@@ -145,6 +203,20 @@ then \
|
|||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for linker option
|
||||||
|
#
|
||||||
|
# $1: Linker option
|
||||||
|
#
|
||||||
|
# Returns the linker option if available and nothing otherwise
|
||||||
|
#
|
||||||
|
define test_linker_flag
|
||||||
|
$(shell printf ".globl _start\n_start:\nnop\n" | \
|
||||||
|
( $(LINK) "-Wl,$1" -o /dev/null -nostdlib -x assembler -) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
||||||
|
endef
|
||||||
|
|
||||||
|
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Support alternate install root
|
# Support alternate install root
|
||||||
#
|
#
|
||||||
@@ -193,6 +265,11 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
|
|||||||
SYSTEMDSYSTEMUNITDIR =
|
SYSTEMDSYSTEMUNITDIR =
|
||||||
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
|
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
|
||||||
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
|
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
|
||||||
|
UDEVDIR = $(USRLIBDIR)/udev
|
||||||
|
UDEVRULESDIR = $(UDEVDIR)/rules.d
|
||||||
|
DRACUTDIR = $(USRLIBDIR)/dracut
|
||||||
|
DRACUTCONFDIR = $(DRACUTDIR)/dracut.conf.d
|
||||||
|
DRACUTMODDIR = $(DRACUTDIR)/modules.d
|
||||||
|
|
||||||
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
|
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
|
||||||
SOINSTALLDIR = $(USRLIB64DIR)
|
SOINSTALLDIR = $(USRLIB64DIR)
|
||||||
@@ -216,10 +293,10 @@ ZFCPDUMP_INITRD = zfcpdump-initrd
|
|||||||
ZFCPDUMP_FLAVOR = zfcpdump
|
ZFCPDUMP_FLAVOR = zfcpdump
|
||||||
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
||||||
|
|
||||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||||
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
CFLAGS_FOR_BUILD ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||||
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
||||||
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
||||||
|
|
||||||
ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||||
@@ -237,6 +314,8 @@ ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
|||||||
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
||||||
ALL_LDFLAGS = $(LDFLAGS)
|
ALL_LDFLAGS = $(LDFLAGS)
|
||||||
|
|
||||||
|
ALL_PERLCFLAGS = $(DEFAULT_PERLCFLAGS)
|
||||||
|
|
||||||
# make G=1
|
# make G=1
|
||||||
# Compile tools so that gcov can be used to collect code coverage data.
|
# Compile tools so that gcov can be used to collect code coverage data.
|
||||||
# See the gcov man page for details.
|
# See the gcov man page for details.
|
||||||
@@ -245,7 +324,7 @@ ALL_CFLAGS := $(filter-out -O%,$(ALL_CFLAGS)) --coverage
|
|||||||
ALL_CXXFLAGS := $(filter-out -O%,$(ALL_CXXFLAGS)) --coverage
|
ALL_CXXFLAGS := $(filter-out -O%,$(ALL_CXXFLAGS)) --coverage
|
||||||
ALL_LDFLAGS += --coverage
|
ALL_LDFLAGS += --coverage
|
||||||
endif
|
endif
|
||||||
export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP INSTALL CFLAGS CXXFLAGS \
|
export INSTALL CFLAGS CXXFLAGS \
|
||||||
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
|
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
|
||||||
|
|
||||||
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||||
@@ -256,7 +335,7 @@ else
|
|||||||
NO_PIE_LDFLAGS :=
|
NO_PIE_LDFLAGS :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Overwrite implicite makefile rules for having nice compile output
|
# Overwrite implicit makefile rules for having nice compile output
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
ifeq ("${C}","1")
|
ifeq ("${C}","1")
|
||||||
$(CHECKTOOL) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
|
$(CHECKTOOL) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
|
||||||
@@ -283,12 +362,13 @@ help:
|
|||||||
@echo ' clean Delete all generated files'
|
@echo ' clean Delete all generated files'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'OPTIONS'
|
@echo 'OPTIONS'
|
||||||
@echo ' D=1 Build with debugging option "-Og"'
|
@echo ' D=1 Build with debugging option "-Og"'
|
||||||
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
||||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||||
@echo ' V=1 Generate verbose build output'
|
@echo ' V=1 Generate verbose build output'
|
||||||
@echo ' W=1 Build with higher warning level'
|
@echo ' W=1 Build with higher warning level'
|
||||||
@echo ' ASAN=1 Build with address sanitizer'
|
@echo ' ASAN=1 Build with address sanitizer'
|
||||||
|
@echo ' ENABLE_WERROR=1 Build with -Werror'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'EXAMPLES'
|
@echo 'EXAMPLES'
|
||||||
@echo ' # make clean all D=1 W=1 -j'
|
@echo ' # make clean all D=1 W=1 -j'
|
||||||
@@ -359,10 +439,6 @@ $(rootdir)/libzds/libzds.a: $(rootdir)/libzds
|
|||||||
$(MAKE) -C $(rootdir)/libzds/ libzds.a
|
$(MAKE) -C $(rootdir)/libzds/ libzds.a
|
||||||
.PHONY: $(rootdir)/libzds
|
.PHONY: $(rootdir)/libzds
|
||||||
|
|
||||||
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
|
|
||||||
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
|
|
||||||
.PHONY: $(rootdir)/libvmdump
|
|
||||||
|
|
||||||
$(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
|
$(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
|
||||||
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
||||||
.PHONY: $(rootdir)/libvmcp
|
.PHONY: $(rootdir)/libvmcp
|
||||||
@@ -391,8 +467,8 @@ $(rootdir)/libpv/libpv.a: $(rootdir)/libpv
|
|||||||
$(MAKE) -C $(rootdir)/libpv libpv.a
|
$(MAKE) -C $(rootdir)/libpv libpv.a
|
||||||
.PHONY: $(rootdir)/libpv
|
.PHONY: $(rootdir)/libpv
|
||||||
|
|
||||||
$(rootdir)/zipl/boot/data.o:
|
$(rootdir)/zipl/boot/.loaders:
|
||||||
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
|
$(MAKE) -C $(rootdir)/zipl/boot/ .loaders
|
||||||
|
|
||||||
install_dirs:
|
install_dirs:
|
||||||
for dir in $(INSTDIRS); do \
|
for dir in $(INSTDIRS); do \
|
||||||
@@ -417,4 +493,3 @@ clean_dep:
|
|||||||
|
|
||||||
clean: clean_echo clean_gcov clean_dep
|
clean: clean_echo clean_gcov clean_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,28 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
|
ifeq (${HAVE_LIBUDEV},0)
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(SKIP) HAVE_LIBUDEV=0
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(SKIP) HAVE_LIBUDEV=0
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
check_dep:
|
||||||
|
$(call check_dep, \
|
||||||
|
"cpacfstatsd", \
|
||||||
|
"libudev.h", \
|
||||||
|
"systemd-devel", \
|
||||||
|
"HAVE_LIBUDEV=0")
|
||||||
|
|
||||||
ALL_CPPFLAGS += -DVERSION=$(VERSION)
|
ALL_CPPFLAGS += -DVERSION=$(VERSION)
|
||||||
|
|
||||||
all: cpacfstats cpacfstatsd
|
all: check_dep cpacfstats cpacfstatsd
|
||||||
|
|
||||||
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o
|
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -ludev -lpthread -o $@
|
||||||
|
|
||||||
cpacfstats: cpacfstats.o stats_sock.o
|
cpacfstats: cpacfstats.o stats_sock.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
@@ -16,6 +33,8 @@ install: all
|
|||||||
$(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *~ cpacfstatsd cpacfstats
|
rm -f *.o *~ cpacfstatsd cpacfstats
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" cpacfstats.1
|
.\" cpacfstats.1
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright IBM Corp. 2015, 2020
|
.\" Copyright IBM Corp. 2015, 2022
|
||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
@@ -32,7 +32,9 @@ cpacfstats \- enable, disable and display CPACF statistical data
|
|||||||
.RB ]
|
.RB ]
|
||||||
.RB [ \-p | \-\-print
|
.RB [ \-p | \-\-print
|
||||||
.I counter
|
.I counter
|
||||||
|
.RB [ \-n | \-\-nonzero]
|
||||||
.RB ]
|
.RB ]
|
||||||
|
.RB [ \-j | \-\-json ]
|
||||||
.
|
.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The cpacfstats client application interacts with the cpacfstatsd daemon and
|
The cpacfstats client application interacts with the cpacfstatsd daemon and
|
||||||
@@ -44,12 +46,347 @@ All counters are initially disabled and must be switched on to measure
|
|||||||
CPACF activities of the system. There is a slight performance penalty with
|
CPACF activities of the system. There is a slight performance penalty with
|
||||||
CPACF counters enabled.
|
CPACF counters enabled.
|
||||||
|
|
||||||
Note: All cryptographic counters are bound to physical CPUs. If you use
|
CPACF activity counters come in two flavors: CPU-MF and PAI. CPU-MF
|
||||||
dedicated CPUs for your LPAR, you obtain only your CPACF activities. If
|
counters are only available on LPARs and have to be authorized. If
|
||||||
your CPUs are shared with other LPARs, their cryptographic activities might
|
they are available, the counters
|
||||||
distort the results. CPACF performance counters are available on LPARs
|
.B des,
|
||||||
only. For security reasons only members of the group \fIcpacfstats\fR are
|
.B aes,
|
||||||
allowed to run the cpacfstats client application.
|
.B sha,
|
||||||
|
.B rng,
|
||||||
|
and
|
||||||
|
.B ecc
|
||||||
|
are made available. These counters can individually be activated,
|
||||||
|
reset, printed, or deactivated. PAI counters are a lot more detailed.
|
||||||
|
The user interface only offers the counters
|
||||||
|
.B pai_user
|
||||||
|
and
|
||||||
|
.B pai_kernel
|
||||||
|
to count CPACF usage in user-space or kernel-space. When printing
|
||||||
|
these counters, detailed counters are shown. The detailed names are:
|
||||||
|
.RS
|
||||||
|
.IP \(bu
|
||||||
|
KM DES,
|
||||||
|
.IP \(bu
|
||||||
|
KM 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KM TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KM DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES-XTS 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES-XTS 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES-XTS 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KM AES-XTS 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC DES,
|
||||||
|
.IP \(bu
|
||||||
|
KMC 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMC TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMC DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMC PRNG,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMA AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF DES,
|
||||||
|
.IP \(bu
|
||||||
|
KMF 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMF TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMF DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMF AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR DES,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMCTR AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO DES,
|
||||||
|
.IP \(bu
|
||||||
|
KMO 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMO TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMO DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMO AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA1,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA256,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA512,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA3-224,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA3-256,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA3-384,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHA3-512,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHAKE 128,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD SHAKE 256,
|
||||||
|
.IP \(bu
|
||||||
|
KIMD GHASH,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA1,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA256,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA512,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA3-224,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA3-256,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA3-384,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHA3-512,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHAKE 128,
|
||||||
|
.IP \(bu
|
||||||
|
KLMD SHAKE 256,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC DES,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC TDES,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KMAC AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC DES,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC TDES,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC DES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC 2key TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC TDES protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 192bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Last Block CMAC AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC XTS Parameter AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCC XTS Parameter AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCC XTS Parameter AES 128bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC XTS Parameter AES 256bit protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult P256,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult P384,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult P521,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult Ed25519,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult Ed448,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult X25519,
|
||||||
|
.IP \(bu
|
||||||
|
PCC Scalar Mult X448,
|
||||||
|
.IP \(bu
|
||||||
|
PRNO SHA512 DRNG,
|
||||||
|
.IP \(bu
|
||||||
|
PRNO TRNG Query Ratio,
|
||||||
|
.IP \(bu
|
||||||
|
PRNO TRNG,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Verify P256,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Verify P384,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Verify P521,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P256,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P384,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P521,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P256 protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P384 protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA ECDSA Sign P521 protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Verify Ed25519,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Verify Ed448,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Sign Ed25519,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Sign Ed448,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Sign Ed25519 protected key,
|
||||||
|
.IP \(bu
|
||||||
|
KDSA EdDSA Sign Ed448 protected key,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO DES,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO 2key TDES,
|
||||||
|
.IP \(bu
|
||||||
|
PCMKO TDES,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO AES 128bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO AES 192bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCMKO AES 256bit,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO ECC P256,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO ECC P384,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO ECC P521,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO ECC Ed25519,
|
||||||
|
.IP \(bu
|
||||||
|
PCKMO ECC Ed448,
|
||||||
|
.IP \(bu
|
||||||
|
Reserved 1, and
|
||||||
|
.IP \(bu
|
||||||
|
Reserved 2.
|
||||||
|
.RE
|
||||||
|
Note that the counters starting with PCKMO and Reserved are only
|
||||||
|
available in the pai_kernel set. Also note that the counters are
|
||||||
|
designed to count successful operations. In the case of KMA this
|
||||||
|
means only complete GCM operations including final hashing are
|
||||||
|
counted.
|
||||||
|
|
||||||
|
Note: CPU-MF based CPACF performance counters are available on LPARs
|
||||||
|
only. PAI counters are available on all hypervisors. For security
|
||||||
|
reasons only members of the group \fIcpacfstats\fR are allowed to run
|
||||||
|
the cpacfstats client application.
|
||||||
|
|
||||||
Example usage scenario:
|
Example usage scenario:
|
||||||
.P
|
.P
|
||||||
@@ -101,12 +438,34 @@ argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
|
|||||||
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
|
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
|
||||||
performance counters are reset to 0.
|
performance counters are reset to 0.
|
||||||
.TP
|
.TP
|
||||||
\fB\-p\fR or \fB\-\-print\fR [counter]
|
\fB\-p\fR or \fB\-\-print\fR [\fB\-n\fR or \fB\-\-nonzero\fR] [counter]
|
||||||
Display the value of one or all CPACF performance counters. The
|
Display the value of one or all CPACF performance counters. The
|
||||||
optional counter argument can be one of: \fBdes\fR, \fBaes\fR,
|
optional counter argument can be one of: \fBdes\fR, \fBaes\fR,
|
||||||
\fBsha\fR, \fBprng\fR, \fBecc\fR, or \fBall\fR. If the counter
|
\fBsha\fR, \fBprng\fR, \fBecc\fR, \fBpai_user\fR, \fBpai_kernel\fR, or
|
||||||
argument is omitted or if there is no argument, all performance
|
\fBall\fR. If the counter argument is omitted or if there is no
|
||||||
counters are displayed.
|
argument, all performance counters are displayed. If the optional
|
||||||
|
\fB\-n\fR or \fB\-\-nonzero\fR argument is given, then only PAI
|
||||||
|
counters that have a non-zero value are printed.
|
||||||
|
.TP
|
||||||
|
\fB\-j\fR or \fB\-\-json\fR
|
||||||
|
Display all activated counters in JSON format. The JSON contains an
|
||||||
|
array of counter objects. Each object contains the property
|
||||||
|
.B counter
|
||||||
|
specifying either a CPU-MF counter of one of the detailed PAI counter.
|
||||||
|
Additional properties include
|
||||||
|
.B error
|
||||||
|
an error number if the counter could not be read,
|
||||||
|
.B value
|
||||||
|
the counter value if the counter could be read,
|
||||||
|
.B space
|
||||||
|
for PAI counters to specify
|
||||||
|
.B user
|
||||||
|
or
|
||||||
|
.B kernel
|
||||||
|
space counter set, and
|
||||||
|
.B counterid
|
||||||
|
for PAI counters to specify the PAI counter number as specified in the
|
||||||
|
Principles of Operation.
|
||||||
.TP
|
.TP
|
||||||
The default command is --print all.
|
The default command is --print all.
|
||||||
.
|
.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* cpacfstats client implementation
|
* cpacfstats client implementation
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2015, 2020
|
* Copyright IBM Corp. 2015, 2022
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -39,17 +39,187 @@ static const char *const usage =
|
|||||||
"\t-d, --disable [counter] Disable one or all counters\n"
|
"\t-d, --disable [counter] Disable one or all counters\n"
|
||||||
"\t-r, --reset [counter] Reset one or all counter values\n"
|
"\t-r, --reset [counter] Reset one or all counter values\n"
|
||||||
"\t-p, --print [counter] Print one or all counter values\n"
|
"\t-p, --print [counter] Print one or all counter values\n"
|
||||||
"\tcounter can be: 'aes' 'des' 'rng' 'sha' 'ecc' or 'all'\n";
|
"\t-n, --nonzero Print all PAI counters\n"
|
||||||
|
"\t-j, --json Print all counter values in JSON format\n"
|
||||||
|
"\tcounter can be: 'aes' 'des' 'rng' 'sha' 'ecc'\n"
|
||||||
|
"\t 'pai_user' 'pai_kernel' or 'all'\n";
|
||||||
|
|
||||||
static const char *const counter_str[] = {
|
static const char *const counter_str[] = {
|
||||||
[DES_FUNCTIONS] = "des",
|
[DES_FUNCTIONS] = "des",
|
||||||
[AES_FUNCTIONS] = "aes",
|
[AES_FUNCTIONS] = "aes",
|
||||||
[SHA_FUNCTIONS] = "sha",
|
[SHA_FUNCTIONS] = "sha",
|
||||||
[PRNG_FUNCTIONS] = "rng",
|
[PRNG_FUNCTIONS] = "rng",
|
||||||
[ECC_FUNCTIONS] = "ecc",
|
[ECC_FUNCTIONS] = "ecc",
|
||||||
[ALL_COUNTER] = "all"
|
[ALL_COUNTER] = "all",
|
||||||
|
[PAI_USER] = "pai_user",
|
||||||
|
[PAI_KERNEL] = "pai_kernel"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Strings for the pai counter details. Note that this is 0-based
|
||||||
|
* while PoP is 1-based.
|
||||||
|
*/
|
||||||
|
static const char *const pai_str[] = {
|
||||||
|
[ 0] = "KM DES",
|
||||||
|
[ 1] = "KM 2key TDES",
|
||||||
|
[ 2] = "KM TDES",
|
||||||
|
[ 3] = "KM DES protected key",
|
||||||
|
[ 4] = "KM 2key TDES protected key",
|
||||||
|
[ 5] = "KM TDES protected key",
|
||||||
|
[ 6] = "KM AES 128bit",
|
||||||
|
[ 7] = "KM AES 192bit",
|
||||||
|
[ 8] = "KM AES 256bit",
|
||||||
|
[ 9] = "KM AES 128bit protected key",
|
||||||
|
[ 10] = "KM AES 192bit protected key",
|
||||||
|
[ 11] = "KM AES 256bit protected key",
|
||||||
|
[ 12] = "KM AES-XTS 128bit",
|
||||||
|
[ 13] = "KM AES-XTS 256bit",
|
||||||
|
[ 14] = "KM AES-XTS 128bit protected key",
|
||||||
|
[ 15] = "KM AES-XTS 256bit protected key",
|
||||||
|
[ 16] = "KMC DES",
|
||||||
|
[ 17] = "KMC 2key TDES",
|
||||||
|
[ 18] = "KMC TDES",
|
||||||
|
[ 19] = "KMC DES protected key",
|
||||||
|
[ 20] = "KMC 2key TDES protected key",
|
||||||
|
[ 21] = "KMC TDES protected key",
|
||||||
|
[ 22] = "KMC AES 128bit",
|
||||||
|
[ 23] = "KMC AES 192bit",
|
||||||
|
[ 24] = "KMC AES 256bit",
|
||||||
|
[ 25] = "KMC AES 128bit protected key",
|
||||||
|
[ 26] = "KMC AES 192bit protected key",
|
||||||
|
[ 27] = "KMC AES 256bit protected key",
|
||||||
|
[ 28] = "KMC PRNG",
|
||||||
|
[ 29] = "KMA AES 128bit",
|
||||||
|
[ 30] = "KMA AES 192bit",
|
||||||
|
[ 31] = "KMA AES 256bit",
|
||||||
|
[ 32] = "KMA AES 128bit protected key",
|
||||||
|
[ 33] = "KMA AES 192bit protected key",
|
||||||
|
[ 34] = "KMA AES 256bit protected key",
|
||||||
|
[ 35] = "KMF DES",
|
||||||
|
[ 36] = "KMF 2key TDES",
|
||||||
|
[ 37] = "KMF TDES",
|
||||||
|
[ 38] = "KMF DES protected key",
|
||||||
|
[ 39] = "KMF 2key TDES protected key",
|
||||||
|
[ 40] = "KMF TDES protected key",
|
||||||
|
[ 41] = "KMF AES 128bit",
|
||||||
|
[ 42] = "KMF AES 192bit",
|
||||||
|
[ 43] = "KMF AES 256bit",
|
||||||
|
[ 44] = "KMF AES 128bit protected key",
|
||||||
|
[ 45] = "KMF AES 192bit protected key",
|
||||||
|
[ 46] = "KMF AES 256bit protected key",
|
||||||
|
[ 47] = "KMCTR DES",
|
||||||
|
[ 48] = "KMCTR 2key TDES",
|
||||||
|
[ 49] = "KMCTR TDES",
|
||||||
|
[ 50] = "KMCTR DES protected key",
|
||||||
|
[ 51] = "KMCTR 2key TDES protected key",
|
||||||
|
[ 52] = "KMCTR TDES protected key",
|
||||||
|
[ 53] = "KMCTR AES 128bit",
|
||||||
|
[ 54] = "KMCTR AES 192bit",
|
||||||
|
[ 55] = "KMCTR AES 256bit",
|
||||||
|
[ 56] = "KMCTR AES 128bit protected key",
|
||||||
|
[ 57] = "KMCTR AES 192bit protected key",
|
||||||
|
[ 58] = "KMCTR AES 256bit protected key",
|
||||||
|
[ 59] = "KMO DES",
|
||||||
|
[ 60] = "KMO 2key TDES",
|
||||||
|
[ 61] = "KMO TDES",
|
||||||
|
[ 62] = "KMO DES protected key",
|
||||||
|
[ 63] = "KMO 2key TDES protected key",
|
||||||
|
[ 64] = "KMO TDES protected key",
|
||||||
|
[ 65] = "KMO AES 128bit",
|
||||||
|
[ 66] = "KMO AES 192bit",
|
||||||
|
[ 67] = "KMO AES 256bit",
|
||||||
|
[ 68] = "KMO AES 128bit protected key",
|
||||||
|
[ 69] = "KMO AES 192bit protected key",
|
||||||
|
[ 70] = "KMO AES 256bit protected key",
|
||||||
|
[ 71] = "KIMD SHA1",
|
||||||
|
[ 72] = "KIMD SHA256",
|
||||||
|
[ 73] = "KIMD SHA512",
|
||||||
|
[ 74] = "KIMD SHA3-224",
|
||||||
|
[ 75] = "KIMD SHA3-256",
|
||||||
|
[ 76] = "KIMD SHA3-384",
|
||||||
|
[ 77] = "KIMD SHA3-512",
|
||||||
|
[ 78] = "KIMD SHAKE 128",
|
||||||
|
[ 79] = "KIMD SHAKE 256",
|
||||||
|
[ 80] = "KIMD GHASH",
|
||||||
|
[ 81] = "KLMD SHA1",
|
||||||
|
[ 82] = "KLMD SHA256",
|
||||||
|
[ 83] = "KLMD SHA512",
|
||||||
|
[ 84] = "KLMD SHA3-224",
|
||||||
|
[ 85] = "KLMD SHA3-256",
|
||||||
|
[ 86] = "KLMD SHA3-384",
|
||||||
|
[ 87] = "KLMD SHA3-512",
|
||||||
|
[ 88] = "KLMD SHAKE 128",
|
||||||
|
[ 89] = "KLMD SHAKE 256",
|
||||||
|
[ 90] = "KMAC DES",
|
||||||
|
[ 91] = "KMAC 2key TDES",
|
||||||
|
[ 92] = "KMAC TDES",
|
||||||
|
[ 93] = "KMAC DES protected key",
|
||||||
|
[ 94] = "KMAC 2key TDES protected key",
|
||||||
|
[ 95] = "KMAC TDES protected key",
|
||||||
|
[ 96] = "KMAC AES 128bit",
|
||||||
|
[ 97] = "KMAC AES 192bit",
|
||||||
|
[ 98] = "KMAC AES 256bit",
|
||||||
|
[ 99] = "KMAC AES 128bit protected key",
|
||||||
|
[100] = "KMAC AES 192bit protected key",
|
||||||
|
[101] = "KMAC AES 256bit protected key",
|
||||||
|
[102] = "PCC Last Block CMAC DES",
|
||||||
|
[103] = "PCC Last Block CMAC 2key TDES",
|
||||||
|
[104] = "PCC Last Block CMAC TDES",
|
||||||
|
[105] = "PCC Last Block CMAC DES protected key",
|
||||||
|
[106] = "PCC Last Block CMAC 2key TDES protected key",
|
||||||
|
[107] = "PCC Last Block CMAC TDES protected key",
|
||||||
|
[108] = "PCC Last Block CMAC AES 128bit",
|
||||||
|
[109] = "PCC Last Block CMAC AES 192bit",
|
||||||
|
[110] = "PCC Last Block CMAC AES 256bit",
|
||||||
|
[111] = "PCC Last Block CMAC AES 128bit protected key",
|
||||||
|
[112] = "PCC Last Block CMAC AES 192bit protected key",
|
||||||
|
[113] = "PCC Last Block CMAC AES 256bit protected key",
|
||||||
|
[114] = "PCC XTS Parameter AES 128bit",
|
||||||
|
[115] = "PCC XTS Parameter AES 256bit",
|
||||||
|
[116] = "PCC XTS Parameter AES 128bit protected key",
|
||||||
|
[117] = "PCC XTS Parameter AES 256bit protected key",
|
||||||
|
[118] = "PCC Scalar Mult P256",
|
||||||
|
[119] = "PCC Scalar Mult P384",
|
||||||
|
[120] = "PCC Scalar Mult P521",
|
||||||
|
[121] = "PCC Scalar Mult Ed25519",
|
||||||
|
[122] = "PCC Scalar Mult Ed448",
|
||||||
|
[123] = "PCC Scalar Mult X25519",
|
||||||
|
[124] = "PCC Scalar Mult X448",
|
||||||
|
[125] = "PRNO SHA512 DRNG",
|
||||||
|
[126] = "PRNO TRNG Query Ratio",
|
||||||
|
[127] = "PRNO TRNG",
|
||||||
|
[128] = "KDSA ECDSA Verify P256",
|
||||||
|
[129] = "KDSA ECDSA Verify P384",
|
||||||
|
[130] = "KDSA ECDSA Verify P521",
|
||||||
|
[131] = "KDSA ECDSA Sign P256",
|
||||||
|
[132] = "KDSA ECDSA Sign P384",
|
||||||
|
[133] = "KDSA ECDSA Sign P521",
|
||||||
|
[134] = "KDSA ECDSA Sign P256 protected key",
|
||||||
|
[135] = "KDSA ECDSA Sign P384 protected key",
|
||||||
|
[136] = "KDSA ECDSA Sign P521 protected key",
|
||||||
|
[137] = "KDSA EdDSA Verify Ed25519",
|
||||||
|
[138] = "KDSA EdDSA Verify Ed448",
|
||||||
|
[139] = "KDSA EdDSA Sign Ed25519",
|
||||||
|
[140] = "KDSA EdDSA Sign Ed448",
|
||||||
|
[141] = "KDSA EdDSA Sign Ed25519 protected key",
|
||||||
|
[142] = "KDSA EdDSA Sign Ed448 protected key",
|
||||||
|
[143] = "PCKMO DES",
|
||||||
|
[144] = "PCKMO 2key TDES",
|
||||||
|
[145] = "PCMKO TDES",
|
||||||
|
[146] = "PCKMO AES 128bit",
|
||||||
|
[147] = "PCKMO AES 192bit",
|
||||||
|
[148] = "PCMKO AES 256bit",
|
||||||
|
[149] = "PCKMO ECC P256",
|
||||||
|
[150] = "PCKMO ECC P384",
|
||||||
|
[151] = "PCKMO ECC P521",
|
||||||
|
[152] = "PCKMO ECC Ed25519",
|
||||||
|
[153] = "PCKMO ECC Ed448",
|
||||||
|
[154] = "Reserved 1",
|
||||||
|
[155] = "Reserved 2"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int paiprintnonzero;
|
||||||
|
|
||||||
|
|
||||||
static int send_query(int s, enum cmd_e cmd, enum ctr_e ctr)
|
static int send_query(int s, enum cmd_e cmd, enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
@@ -62,7 +232,7 @@ static int send_query(int s, enum cmd_e cmd, enum ctr_e ctr)
|
|||||||
m.query.m_ctr = ctr;
|
m.query.m_ctr = ctr;
|
||||||
m.query.m_cmd = cmd;
|
m.query.m_cmd = cmd;
|
||||||
|
|
||||||
return send_msg(s, &m);
|
return send_msg(s, &m, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,7 +241,7 @@ static int recv_answer(int s, int *ctr, int *state, uint64_t *value)
|
|||||||
struct msg m;
|
struct msg m;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = recv_msg(s, &m);
|
rc = recv_msg(s, &m, 0);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
if (m.head.m_ver != VERSION) {
|
if (m.head.m_ver != VERSION) {
|
||||||
eprint("Received msg with wrong version %d != %d\n",
|
eprint("Received msg with wrong version %d != %d\n",
|
||||||
@@ -92,9 +262,139 @@ static int recv_answer(int s, int *ctr, int *state, uint64_t *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_answer(int ctr, int state, uint64_t value)
|
static void printjsonsep(void)
|
||||||
{
|
{
|
||||||
if (state < 0)
|
static const char *jsonsep = "";
|
||||||
|
|
||||||
|
fputs(jsonsep, stdout);
|
||||||
|
jsonsep = ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void json_print_virtual_counter_answer(int s, int ctr,
|
||||||
|
int state, uint64_t value)
|
||||||
|
{
|
||||||
|
int paictr = 0, paistate = 0, ec;
|
||||||
|
uint64_t i, paivalue = 0, maxnum;
|
||||||
|
const char *space;
|
||||||
|
|
||||||
|
switch (ctr) {
|
||||||
|
case HOTPLUG_DETECTED:
|
||||||
|
printjsonsep();
|
||||||
|
printf("{\"counter\":\"hotplug detected\",");
|
||||||
|
if (state < 0)
|
||||||
|
printf("\"error\":%d}", state);
|
||||||
|
else
|
||||||
|
printf("\"value\":%d}", !!value);
|
||||||
|
return;
|
||||||
|
case PAI_USER:
|
||||||
|
maxnum = NUM_PAI_USER;
|
||||||
|
space = "user";
|
||||||
|
break;
|
||||||
|
case PAI_KERNEL:
|
||||||
|
maxnum = NUM_PAI_KERNEL;
|
||||||
|
space = "kernel";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Here, we have validated the PAI counter retrieved, but not
|
||||||
|
* yet printed. */
|
||||||
|
if (state != ENABLED)
|
||||||
|
return;
|
||||||
|
if (value > maxnum) {
|
||||||
|
eprint("Incompatible versions detected!\n");
|
||||||
|
eprint("Expected %"PRIu64" counter space for %s, but got %"PRIu64"\n",
|
||||||
|
maxnum, space, value);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
for (i = 0; i < value; ++i) {
|
||||||
|
ec = recv_answer(s, &paictr, &paistate, &paivalue);
|
||||||
|
if (ec < 0 || paistate < 0) {
|
||||||
|
eprint("Error on receiving answer message from daemon\n");
|
||||||
|
/* No more data for this virtual event after error. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (paictr > NUM_PAI_KERNEL) {
|
||||||
|
eprint("Pai counter number too big: %d\n", paictr);
|
||||||
|
} else {
|
||||||
|
printjsonsep();
|
||||||
|
printf("{\"counter\":\"%s\",\"space\":\"%s\",\"counterid\":%d,",
|
||||||
|
pai_str[paictr], space, paictr + 1);
|
||||||
|
if (paistate < 0) {
|
||||||
|
printf("\"error\":%d}", paistate);
|
||||||
|
/* Protocol does not send further counters. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("\"value\":%"PRIu64"}", paivalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void print_virtual_counter_answer(int s,
|
||||||
|
int ctr, int state, uint64_t value)
|
||||||
|
{
|
||||||
|
static const char *const states[] = {
|
||||||
|
[DISABLED] = "disabled",
|
||||||
|
[ENABLED] = "enabled",
|
||||||
|
[UNSUPPORTED] = "unsupported"
|
||||||
|
};
|
||||||
|
int paictr = 0, paistate = 0, ec;
|
||||||
|
uint64_t i, paivalue = 0, maxnum;
|
||||||
|
const char *ctrstr;
|
||||||
|
|
||||||
|
switch (ctr) {
|
||||||
|
case HOTPLUG_DETECTED:
|
||||||
|
if (state >= 0 && value > 0)
|
||||||
|
printf(" hotplug detected\n");
|
||||||
|
return;
|
||||||
|
case PAI_USER:
|
||||||
|
maxnum = NUM_PAI_USER;
|
||||||
|
ctrstr = "pai_user";
|
||||||
|
break;
|
||||||
|
case PAI_KERNEL:
|
||||||
|
maxnum = NUM_PAI_KERNEL;
|
||||||
|
ctrstr = "pai_kernel";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Here, we have validated the PAI counter retrieved, but not
|
||||||
|
* yet printed. */
|
||||||
|
if (state < 0 || state > UNSUPPORTED) {
|
||||||
|
printf(" %11s: error state %d\n", ctrstr, state);
|
||||||
|
/* No details follow if counter in error state. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf(" %-11s: %s\n", ctrstr, states[state]);
|
||||||
|
if (state != ENABLED)
|
||||||
|
return;
|
||||||
|
if (value > maxnum) {
|
||||||
|
eprint("Incompatible versions detected!\n");
|
||||||
|
eprint("Expected %"PRIu64" counters for %s, but got %"PRIu64"\n",
|
||||||
|
maxnum, ctrstr, value);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
for (i = 0; i < value; ++i) {
|
||||||
|
ec = recv_answer(s, &paictr, &paistate, &paivalue);
|
||||||
|
if (ec < 0 || paistate < 0) {
|
||||||
|
eprint("Error on receiving answer message from daemon\n");
|
||||||
|
/* No more data for this virtual event after error. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (paictr > NUM_PAI_KERNEL)
|
||||||
|
eprint("Pai counter number too big: %d\n", paictr);
|
||||||
|
else if (!paiprintnonzero || paivalue > 0)
|
||||||
|
printf(" %-45s: %"PRIu64"\n", pai_str[paictr], paivalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_answer(int s, int ctr, int state, uint64_t value)
|
||||||
|
{
|
||||||
|
if (ctr > ALL_COUNTER)
|
||||||
|
print_virtual_counter_answer(s, ctr, state, value);
|
||||||
|
else if (state < 0)
|
||||||
printf(" %s counter: error state %d\n",
|
printf(" %s counter: error state %d\n",
|
||||||
counter_str[ctr], state);
|
counter_str[ctr], state);
|
||||||
else if (state == DISABLED)
|
else if (state == DISABLED)
|
||||||
@@ -106,6 +406,22 @@ static void print_answer(int ctr, int state, uint64_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void json_print_answer(int s, int ctr, int state, uint64_t value)
|
||||||
|
{
|
||||||
|
if (ctr > ALL_COUNTER) {
|
||||||
|
json_print_virtual_counter_answer(s, ctr, state, value);
|
||||||
|
} else if (state < 0) {
|
||||||
|
printjsonsep();
|
||||||
|
printf("{\"counter\":\"%s\",", counter_str[ctr]);
|
||||||
|
printf("\"error\":%d}\n", state);
|
||||||
|
} else if (state == ENABLED) {
|
||||||
|
printjsonsep();
|
||||||
|
printf("{\"counter\":\"%s\",", counter_str[ctr]);
|
||||||
|
printf("\"value\":%"PRIu64"}", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eprint(const char *format, ...)
|
int eprint(const char *format, ...)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@@ -128,7 +444,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
enum ctr_e ctr = ALL_COUNTER;
|
enum ctr_e ctr = ALL_COUNTER;
|
||||||
enum cmd_e cmd = PRINT;
|
enum cmd_e cmd = PRINT;
|
||||||
int i, j, s, state;
|
int i, j, s, state, num, json = 0;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -140,98 +456,108 @@ int main(int argc, char *argv[])
|
|||||||
{ "disable", 0, NULL, 'd' },
|
{ "disable", 0, NULL, 'd' },
|
||||||
{ "reset", 0, NULL, 'r' },
|
{ "reset", 0, NULL, 'r' },
|
||||||
{ "print", 0, NULL, 'p' },
|
{ "print", 0, NULL, 'p' },
|
||||||
|
{ "nonzero", 0, NULL, 'n' },
|
||||||
|
{ "json", 0, NULL, 'j' },
|
||||||
{ NULL, 0, NULL, 0 } };
|
{ NULL, 0, NULL, 0 } };
|
||||||
while (1) {
|
while (1) {
|
||||||
opt = getopt_long(argc, argv,
|
opt = getopt_long(argc, argv,
|
||||||
"hvedrp", long_opts, &idx);
|
"hvedrpnj", long_opts, &idx);
|
||||||
if (opt == -1)
|
if (opt == -1)
|
||||||
break; /* no more arguments */
|
break; /* no more arguments */
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
printf(usage, name);
|
printf(usage, name);
|
||||||
exit(0);
|
return 0;
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
printf("%s: Linux on System z CPACF Crypto Activity Counters Client\n"
|
printf("%s: Linux on System z CPACF Crypto Activity Counters Client\n"
|
||||||
"Version %s\n%s\n",
|
"Version %s\n%s\n",
|
||||||
name, RELEASE_STRING, COPYRIGHT);
|
name, RELEASE_STRING, COPYRIGHT);
|
||||||
exit(0);
|
return 0;
|
||||||
break;
|
|
||||||
case 'e':
|
case 'e':
|
||||||
cmd = ENABLE;
|
cmd = ENABLE;
|
||||||
|
json = 0;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
cmd = DISABLE;
|
cmd = DISABLE;
|
||||||
|
json = 0;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
cmd = RESET;
|
cmd = RESET;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
cmd = PRINT;
|
cmd = PRINT;
|
||||||
|
json = 0;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
paiprintnonzero = 1;
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
cmd = PRINT;
|
||||||
|
json = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
eprint("Invalid argument, try -h or --help for more information\n");
|
eprint("Invalid argument, try -h or --help for more information\n");
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* there may be an optional counter argument */
|
/* there may be an optional counter argument */
|
||||||
if (optind > 0 && optind < argc) {
|
if (optind > 0 && optind < argc) {
|
||||||
for (i = 0; i <= ALL_COUNTER; i++)
|
for (i = 0; i < NUM_COUNTER; i++)
|
||||||
if (strcmp(argv[optind], counter_str[i]) == 0)
|
if (strcmp(argv[optind], counter_str[i]) == 0)
|
||||||
break;
|
break;
|
||||||
if (i > ALL_COUNTER) {
|
if (i >= NUM_COUNTER) {
|
||||||
eprint("Unknown counter '%s'\n", argv[optind]);
|
eprint("Unknown counter '%s'\n", argv[optind]);
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
ctr = (enum ctr_e) i;
|
ctr = (enum ctr_e) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (json)
|
||||||
|
ctr = ALL_COUNTER;
|
||||||
|
|
||||||
/* try to open and connect socket to the cpacfstatsd daemon */
|
/* try to open and connect socket to the cpacfstatsd daemon */
|
||||||
s = open_socket(CLIENT);
|
s = open_socket(CLIENT);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
eprint("Can't connect to daemon\n");
|
eprint("Can't connect to daemon\n");
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send query */
|
/* send query */
|
||||||
if (send_query(s, cmd, ctr) != 0) {
|
if (send_query(s, cmd, ctr) != 0) {
|
||||||
eprint("Error on sending query message to daemon\n");
|
eprint("Error on sending query message to daemon\n");
|
||||||
close(s);
|
close(s);
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctr == ALL_COUNTER) {
|
if (ctr == ALL_COUNTER) {
|
||||||
for (i = 0; i < ALL_COUNTER; i++) {
|
/* The -1 is for ALL_COUNTER which is not sent, +1 for
|
||||||
/* receive answer */
|
* hotplug state. */
|
||||||
if (recv_answer(s, &j, &state, &value) != 0) {
|
num = NUM_COUNTER - 1 + 1;
|
||||||
eprint("Error on receiving answer message from daemon\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (state < 0) {
|
|
||||||
eprint("Received bad status code %d from daemon\n",
|
|
||||||
state);
|
|
||||||
close(s);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
print_answer(j, state, value);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
/* +1 for hotplug state */
|
||||||
|
num = 1 + 1;
|
||||||
|
}
|
||||||
|
if (json)
|
||||||
|
putchar('[');
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
/* receive answer */
|
/* receive answer */
|
||||||
if (recv_answer(s, &j, &state, &value) != 0) {
|
if (recv_answer(s, &j, &state, &value) != 0) {
|
||||||
eprint("Error on receiving answer message from daemon\n");
|
eprint("Error on receiving answer message from daemon\n");
|
||||||
close(s);
|
return EXIT_FAILURE;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
if (state < 0) {
|
if (state < 0) {
|
||||||
eprint("Received bad status code %d from daemon\n",
|
eprint("Received bad status code %d from daemon\n",
|
||||||
state);
|
state);
|
||||||
close(s);
|
close(s);
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
print_answer(j, state, value);
|
if (json)
|
||||||
|
json_print_answer(s, j, state, value);
|
||||||
|
else
|
||||||
|
print_answer(s, j, state, value);
|
||||||
}
|
}
|
||||||
|
if (json)
|
||||||
|
putchar(']');
|
||||||
|
|
||||||
/* close connection */
|
/* close connection */
|
||||||
close(s);
|
close(s);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* common function prototypes and definitions
|
* common function prototypes and definitions
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2015, 2020
|
* Copyright IBM Corp. 2015, 2022
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -14,13 +14,27 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#define COPYRIGHT "Copyright IBM Corp. 2015, 2020"
|
#define COPYRIGHT "Copyright IBM Corp. 2015, 2022"
|
||||||
|
|
||||||
|
#define DEFAULT_SEND_TIMEOUT (30 * 1000)
|
||||||
|
#define DEFAULT_RECV_TIMEOUT (30 * 1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of PAI counters for user space. This excludes PCKMO since
|
||||||
|
* this instruction is privileged.
|
||||||
|
*/
|
||||||
|
#define NUM_PAI_USER 143
|
||||||
|
/* Number of PAI counters for kernel space. Contains all counters. */
|
||||||
|
#define NUM_PAI_KERNEL 156
|
||||||
|
|
||||||
int eprint(const char *format, ...);
|
int eprint(const char *format, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Counter names
|
* Counter names
|
||||||
* ALL_COUNTER must always be the last member of the enum
|
* ALL_COUNTER specifies the number of physical counters. Virtual
|
||||||
|
* counters might be added afterwards. NUM_COUNTER is the last
|
||||||
|
* managed counter (i.e., a counter that can be activated, reset,
|
||||||
|
* deactivated).
|
||||||
*/
|
*/
|
||||||
enum ctr_e {
|
enum ctr_e {
|
||||||
DES_FUNCTIONS = 0,
|
DES_FUNCTIONS = 0,
|
||||||
@@ -28,7 +42,11 @@ enum ctr_e {
|
|||||||
SHA_FUNCTIONS,
|
SHA_FUNCTIONS,
|
||||||
PRNG_FUNCTIONS,
|
PRNG_FUNCTIONS,
|
||||||
ECC_FUNCTIONS,
|
ECC_FUNCTIONS,
|
||||||
ALL_COUNTER
|
ALL_COUNTER,
|
||||||
|
PAI_USER,
|
||||||
|
PAI_KERNEL,
|
||||||
|
NUM_COUNTER,
|
||||||
|
HOTPLUG_DETECTED = 0xffff
|
||||||
};
|
};
|
||||||
|
|
||||||
enum type_e {
|
enum type_e {
|
||||||
@@ -50,7 +68,7 @@ enum state_e {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* query send from clent to daemon
|
* query send from client to daemon
|
||||||
* Consist of:
|
* Consist of:
|
||||||
* enum counter
|
* enum counter
|
||||||
* enum command
|
* enum command
|
||||||
@@ -63,7 +81,7 @@ struct msg_query {
|
|||||||
/*
|
/*
|
||||||
* answer send from daemon to client
|
* answer send from daemon to client
|
||||||
* Consist of:
|
* Consist of:
|
||||||
* enum counter
|
* enum counter or PAI counter number if following PAI_USER or PAI_KERNEL
|
||||||
* status code: < 0 error, 0 disabled, > 0 enabled
|
* status code: < 0 error, 0 disabled, > 0 enabled
|
||||||
* counter value
|
* counter value
|
||||||
*/
|
*/
|
||||||
@@ -99,17 +117,20 @@ struct msg {
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
int open_socket(int mode);
|
int open_socket(int mode);
|
||||||
int send_msg(int sfd, struct msg *m);
|
int send_msg(int sfd, struct msg *m, int timeout);
|
||||||
int recv_msg(int sfd, struct msg *m);
|
int recv_msg(int sfd, struct msg *m, int timeout);
|
||||||
|
|
||||||
/* perf_crypto.c */
|
/* perf_crypto.c */
|
||||||
|
|
||||||
int perf_init(void);
|
int perf_init(void);
|
||||||
|
void perf_stop(void);
|
||||||
void perf_close(void);
|
void perf_close(void);
|
||||||
int perf_enable_ctr(enum ctr_e ctr);
|
int perf_enable_ctr(enum ctr_e ctr);
|
||||||
int perf_disable_ctr(enum ctr_e ctr);
|
int perf_disable_ctr(enum ctr_e ctr);
|
||||||
int perf_reset_ctr(enum ctr_e ctr);
|
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value);
|
||||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value);
|
int perf_read_ctr(enum ctr_e ctr, uint64_t *value);
|
||||||
int perf_ecc_supported(void);
|
int perf_ecc_supported(void);
|
||||||
|
int perf_ctr_state(enum ctr_e ctr);
|
||||||
|
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,9 +45,8 @@ counter set authorization control" checkbox.
|
|||||||
- The daemon requires root privileges to interact with the performance
|
- The daemon requires root privileges to interact with the performance
|
||||||
ioctls of the kernel.
|
ioctls of the kernel.
|
||||||
|
|
||||||
CPU hotplug is not recognized by the daemon. When adding or removing a CPU,
|
CPU hotplug is recognized by the daemon. When adding or removing a CPU,
|
||||||
restart the daemon to ensure correct summing of the per-CPU performance
|
the daemon ensures correct summing of the per-CPU performance counters.
|
||||||
counters.
|
|
||||||
|
|
||||||
The starting daemon first checks for any stale pid file
|
The starting daemon first checks for any stale pid file
|
||||||
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* cpacfstatsd daemon implementation
|
* cpacfstatsd daemon implementation
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2015, 2017
|
* Copyright IBM Corp. 2015, 2022
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "cpacfstats.h"
|
#include "cpacfstats.h"
|
||||||
|
|
||||||
|
static volatile int stopsig;
|
||||||
|
|
||||||
static const char *const name = "cpacfstatsd";
|
static const char *const name = "cpacfstatsd";
|
||||||
|
|
||||||
@@ -43,15 +44,12 @@ static const char *const usage =
|
|||||||
|
|
||||||
static int daemonized;
|
static int daemonized;
|
||||||
|
|
||||||
static int ctr_state[ALL_COUNTER];
|
|
||||||
|
|
||||||
|
|
||||||
static int recv_query(int s, enum ctr_e *ctr, enum cmd_e *cmd)
|
static int recv_query(int s, enum ctr_e *ctr, enum cmd_e *cmd)
|
||||||
{
|
{
|
||||||
struct msg m;
|
struct msg m;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = recv_msg(s, &m);
|
rc = recv_msg(s, &m, DEFAULT_RECV_TIMEOUT);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
if (m.head.m_ver != VERSION) {
|
if (m.head.m_ver != VERSION) {
|
||||||
eprint("Received msg with wrong version %d != %d\n",
|
eprint("Received msg with wrong version %d != %d\n",
|
||||||
@@ -83,38 +81,82 @@ static int send_answer(int s, int ctr, int state, uint64_t value)
|
|||||||
m.answer.m_state = state;
|
m.answer.m_state = state;
|
||||||
m.answer.m_value = value;
|
m.answer.m_value = value;
|
||||||
|
|
||||||
return send_msg(s, &m);
|
return send_msg(s, &m, DEFAULT_SEND_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print according to protocol for PAI:
|
||||||
|
* - first the state and the number of PAI counters that follow
|
||||||
|
* - if state is ENABLED:
|
||||||
|
* - for each PAI counter the value with state ENABLED
|
||||||
|
* Note that the PAI counters are 0-based, not 1 based as in PoP!
|
||||||
|
* Sending ends with the first error.
|
||||||
|
*/
|
||||||
|
static int do_send_pai(int s, int user)
|
||||||
|
{
|
||||||
|
int ctr, state, i, maxctr, rc = 0;
|
||||||
|
uint64_t value;
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
ctr = PAI_USER;
|
||||||
|
maxctr = NUM_PAI_USER;
|
||||||
|
} else {
|
||||||
|
ctr = PAI_KERNEL;
|
||||||
|
maxctr = NUM_PAI_KERNEL;
|
||||||
|
}
|
||||||
|
state = perf_ctr_state(ctr);
|
||||||
|
if (state != ENABLED)
|
||||||
|
return rc;
|
||||||
|
for (i = 0; i < maxctr; ++i) {
|
||||||
|
rc = perf_read_pai_ctr(i, user, &value);
|
||||||
|
if (rc != 0) {
|
||||||
|
send_answer(s, i, rc, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
send_answer(s, i, state, value);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_enable(int s, enum ctr_e ctr)
|
static int do_enable(int s, enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint64_t value = 0;
|
||||||
int i, rc = 0;
|
int i, rc = 0;
|
||||||
|
int state;
|
||||||
|
|
||||||
for (i = 0; i < ALL_COUNTER; i++) {
|
for (i = 0; i < NUM_COUNTER; i++) {
|
||||||
|
if (i == ALL_COUNTER)
|
||||||
|
continue;
|
||||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||||
if (ctr_state[i] == DISABLED) {
|
state = perf_ctr_state(i);
|
||||||
|
if (state == DISABLED) {
|
||||||
rc = perf_enable_ctr(i);
|
rc = perf_enable_ctr(i);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_answer(s, i, rc, 0);
|
send_answer(s, i, rc, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctr_state[i] = ENABLED;
|
state = ENABLED;
|
||||||
}
|
}
|
||||||
if (ctr_state[i] == UNSUPPORTED) {
|
if (state != UNSUPPORTED) {
|
||||||
send_answer(s, i, UNSUPPORTED, 0);
|
|
||||||
} else {
|
|
||||||
rc = perf_read_ctr(i, &value);
|
rc = perf_read_ctr(i, &value);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_answer(s, i, rc, 0);
|
send_answer(s, i, rc, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
send_answer(s, i, ENABLED, value);
|
|
||||||
}
|
}
|
||||||
|
send_answer(s, i, state, value);
|
||||||
|
if (i == PAI_USER)
|
||||||
|
rc = do_send_pai(s, 1);
|
||||||
|
if (i == PAI_KERNEL)
|
||||||
|
rc = do_send_pai(s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||||
|
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,85 +164,114 @@ static int do_enable(int s, enum ctr_e ctr)
|
|||||||
static int do_disable(int s, enum ctr_e ctr)
|
static int do_disable(int s, enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
int i, rc = 0;
|
int i, rc = 0;
|
||||||
|
uint64_t value;
|
||||||
|
|
||||||
for (i = 0; i < ALL_COUNTER; i++) {
|
for (i = 0; i < NUM_COUNTER; i++) {
|
||||||
|
if (i == ALL_COUNTER)
|
||||||
|
continue;
|
||||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||||
if (ctr_state[i] == ENABLED) {
|
if (perf_ctr_state(i) == ENABLED) {
|
||||||
rc = perf_disable_ctr(i);
|
rc = perf_disable_ctr(i);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_answer(s, i, rc, 0);
|
send_answer(s, i, rc, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctr_state[i] = 0;
|
|
||||||
}
|
}
|
||||||
send_answer(s, i, ctr_state[i], 0);
|
send_answer(s, i, perf_ctr_state(i), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||||
|
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_reset(int s, enum ctr_e ctr)
|
static int do_reset(int s, enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
int i, rc = 0;
|
int i, rc = 0, state;
|
||||||
|
uint64_t value;
|
||||||
|
|
||||||
for (i = 0; i < ALL_COUNTER; i++) {
|
for (i = 0; i < NUM_COUNTER; i++) {
|
||||||
|
if (i == ALL_COUNTER)
|
||||||
|
continue;
|
||||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||||
if (ctr_state[i] == ENABLED) {
|
state = perf_ctr_state(i);
|
||||||
rc = perf_reset_ctr(i);
|
if (state == ENABLED) {
|
||||||
|
rc = perf_reset_ctr(i, &value);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_answer(s, i, rc, 0);
|
send_answer(s, i, rc, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
send_answer(s, i, ENABLED, 0);
|
|
||||||
} else {
|
|
||||||
send_answer(s, i, ctr_state[i], 0);
|
|
||||||
}
|
}
|
||||||
|
send_answer(s, i, state, value);
|
||||||
|
if (i == PAI_USER)
|
||||||
|
rc = do_send_pai(s, 1);
|
||||||
|
if (i == PAI_KERNEL)
|
||||||
|
rc = do_send_pai(s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||||
|
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_print(int s, enum ctr_e ctr)
|
static int do_print(int s, enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
int i, rc = 0;
|
int i, rc = 0, state;
|
||||||
uint64_t value;
|
uint64_t value = 0;
|
||||||
|
|
||||||
for (i = 0; i < ALL_COUNTER; i++) {
|
for (i = 0; i < NUM_COUNTER; i++) {
|
||||||
|
if (i == ALL_COUNTER)
|
||||||
|
continue;
|
||||||
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
if (i == (int) ctr || ctr == ALL_COUNTER) {
|
||||||
if (ctr_state[i] == ENABLED) {
|
state = perf_ctr_state(i);
|
||||||
|
if (state == ENABLED) {
|
||||||
rc = perf_read_ctr(i, &value);
|
rc = perf_read_ctr(i, &value);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
send_answer(s, i, rc, 0);
|
send_answer(s, i, rc, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
send_answer(s, i, ENABLED, value);
|
|
||||||
} else {
|
|
||||||
send_answer(s, i, ctr_state[i], 0);
|
|
||||||
}
|
}
|
||||||
|
send_answer(s, i, state, value);
|
||||||
|
if (i == PAI_USER)
|
||||||
|
rc = do_send_pai(s, 1);
|
||||||
|
if (i == PAI_KERNEL)
|
||||||
|
rc = do_send_pai(s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
|
||||||
|
send_answer(s, HOTPLUG_DETECTED, rc, value);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int become_daemon(void)
|
static int become_daemon(int *startup_pipe)
|
||||||
{
|
{
|
||||||
|
int child_initialized = 0, fd;
|
||||||
|
int pipefds[2];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* syslog */
|
/* syslog */
|
||||||
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
||||||
|
|
||||||
|
if (pipe(pipefds) != 0) {
|
||||||
|
eprint("pipe() failed, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fork and terminate parent
|
* fork and terminate parent
|
||||||
* Reasons:
|
* Reasons:
|
||||||
* - opens new command line prompt
|
* - opens new command line prompt
|
||||||
* - the child process is guaranteed not to be the process group leader
|
* - the child process is guaranteed not to be the process group leader
|
||||||
* nessecarry for setsid.
|
* necessary for setsid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
@@ -211,9 +282,23 @@ static int become_daemon(void)
|
|||||||
case 0: /* child */
|
case 0: /* child */
|
||||||
break;
|
break;
|
||||||
default: /* parent */
|
default: /* parent */
|
||||||
|
(void)close(pipefds[1]);
|
||||||
|
if (read(pipefds[0], &child_initialized, sizeof(child_initialized)) !=
|
||||||
|
sizeof(child_initialized)) {
|
||||||
|
eprint("Couldn't read from PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
if (!child_initialized)
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Executed within the child context only */
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
*startup_pipe = pipefds[1];
|
||||||
|
|
||||||
if (chdir("/") != 0) {
|
if (chdir("/") != 0) {
|
||||||
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
@@ -324,18 +409,8 @@ static void remove_pidfile(void)
|
|||||||
|
|
||||||
void signalhandler(int sig)
|
void signalhandler(int sig)
|
||||||
{
|
{
|
||||||
if (sig == SIGTERM)
|
perf_stop();
|
||||||
eprint("Caught signal SIGTERM, terminating...\n");
|
stopsig = sig;
|
||||||
else if (sig == SIGINT)
|
|
||||||
eprint("Caught signal SIGINT, terminating...\n");
|
|
||||||
else
|
|
||||||
eprint("Caught signal %d, terminating...\n", sig);
|
|
||||||
|
|
||||||
remove_sock();
|
|
||||||
perf_close();
|
|
||||||
remove_pidfile();
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -363,7 +438,7 @@ int eprint(const char *format, ...)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, sfd, foreground = 0;
|
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -381,7 +456,7 @@ int main(int argc, char *argv[])
|
|||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
printf(usage, name);
|
printf(usage, name);
|
||||||
exit(0);
|
return 0;
|
||||||
case 'f':
|
case 'f':
|
||||||
foreground = 1;
|
foreground = 1;
|
||||||
break;
|
break;
|
||||||
@@ -389,40 +464,37 @@ int main(int argc, char *argv[])
|
|||||||
printf("%s: Linux on System z CPACF Crypto Activity Counters Daemon\n"
|
printf("%s: Linux on System z CPACF Crypto Activity Counters Daemon\n"
|
||||||
"Version %s\n%s\n",
|
"Version %s\n%s\n",
|
||||||
name, RELEASE_STRING, COPYRIGHT);
|
name, RELEASE_STRING, COPYRIGHT);
|
||||||
exit(0);
|
return 0;
|
||||||
default:
|
default:
|
||||||
printf("%s: Invalid argument, try -h or --help for more information\n",
|
printf("%s: Invalid argument, try -h or --help for more information\n",
|
||||||
name);
|
name);
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_pidfile() != 0) {
|
if (check_pidfile() != 0) {
|
||||||
eprint("Stalled pid file or daemon allready running, terminating\n");
|
eprint("Stalled pid file or daemon already running, terminating\n");
|
||||||
exit(1);
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foreground) {
|
if (!foreground) {
|
||||||
if (become_daemon() != 0) {
|
if (become_daemon(&startup_pipe) != 0) {
|
||||||
eprint("Couldn't daemonize\n");
|
eprint("Couldn't daemonize\n");
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_init() != 0) {
|
if (perf_init() != 0) {
|
||||||
eprint("Couldn't initialize perf lib\n");
|
eprint("Couldn't initialize perf lib\n");
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
atexit(perf_close);
|
atexit(perf_close);
|
||||||
|
|
||||||
if (!perf_ecc_supported())
|
|
||||||
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
|
|
||||||
|
|
||||||
sfd = open_socket(SERVER);
|
sfd = open_socket(SERVER);
|
||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
eprint("Couldn't initialize server socket\n");
|
eprint("Couldn't initialize server socket\n");
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
atexit(remove_sock);
|
atexit(remove_sock);
|
||||||
|
|
||||||
@@ -432,17 +504,29 @@ int main(int argc, char *argv[])
|
|||||||
if (sigaction(SIGINT, &act, 0) != 0) {
|
if (sigaction(SIGINT, &act, 0) != 0) {
|
||||||
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
if (sigaction(SIGTERM, &act, 0) != 0) {
|
if (sigaction(SIGTERM, &act, 0) != 0) {
|
||||||
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
|
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
eprint("Running\n");
|
eprint("Running\n");
|
||||||
|
initialized = 1;
|
||||||
|
/* `startup_pipe` has been initialized, so we know we are
|
||||||
|
* running in daemon mode. Let's write to the pipe so that the
|
||||||
|
* parent knows that the initialization is complete.
|
||||||
|
*/
|
||||||
|
if (startup_pipe != -1 &&
|
||||||
|
write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||||
|
goto error;
|
||||||
|
(void)close(startup_pipe);
|
||||||
|
startup_pipe = -1;
|
||||||
|
|
||||||
while (1) {
|
while (!stopsig) {
|
||||||
enum ctr_e ctr;
|
enum ctr_e ctr;
|
||||||
enum cmd_e cmd;
|
enum cmd_e cmd;
|
||||||
int s;
|
int s;
|
||||||
@@ -453,13 +537,14 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
eprint("Accept() failure, errno=%d [%s]\n",
|
eprint("Accept() failure, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
exit(1);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = recv_query(s, &ctr, &cmd);
|
rc = recv_query(s, &ctr, &cmd);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
eprint("Recv_query() failed, ignoring\n");
|
eprint("Recv_query() failed, ignoring\n");
|
||||||
goto cleanup;
|
close(s);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == ENABLE)
|
if (cmd == ENABLE)
|
||||||
@@ -473,12 +558,28 @@ int main(int argc, char *argv[])
|
|||||||
else {
|
else {
|
||||||
eprint("Received unknown command %d, ignoring\n",
|
eprint("Received unknown command %d, ignoring\n",
|
||||||
(int) cmd);
|
(int) cmd);
|
||||||
goto cleanup;
|
close(s);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
close(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stopsig == SIGTERM)
|
||||||
|
eprint("Caught signal SIGTERM, terminating...\n");
|
||||||
|
else if (stopsig == SIGINT)
|
||||||
|
eprint("Caught signal SIGINT, terminating...\n");
|
||||||
|
else
|
||||||
|
eprint("Caught signal %d, terminating...\n", stopsig);
|
||||||
|
remove_pidfile();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (startup_pipe != -1) {
|
||||||
|
/* Notify the parent process that there was an error */
|
||||||
|
if (write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||||
|
eprint("Couldn't write to PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
(void)close(startup_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* low level perf functions
|
* low level perf functions
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2015, 2020
|
* Copyright IBM Corp. 2015, 2022
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -16,14 +16,21 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <libudev.h>
|
||||||
|
|
||||||
#include "cpacfstats.h"
|
#include "cpacfstats.h"
|
||||||
|
#include "../include/lib/zt_common.h"
|
||||||
|
|
||||||
/* correlation between counter and perf counter string */
|
/* correlation between counter and perf counter string */
|
||||||
static const struct {
|
static const struct {
|
||||||
@@ -38,25 +45,83 @@ static const struct {
|
|||||||
{"cpum_cf", "ECC_FUNCTION_COUNT", ECC_FUNCTIONS}
|
{"cpum_cf", "ECC_FUNCTION_COUNT", ECC_FUNCTIONS}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
static struct pmf_data {
|
||||||
* We need one filedescriptor per CPU per counter.
|
int pmutype;
|
||||||
* So perf_init builds this:
|
int eventid;
|
||||||
*
|
} pmf_counter_data[ALL_COUNTER];
|
||||||
* ctr_fds - is an array of pointers to file descriptor arrays.
|
|
||||||
* Each file descriptor array has space for number of logical CPUs + 1
|
|
||||||
* filedescriptors (int values). The last element of each file descriptor
|
|
||||||
* array is always 0, assuming there will never appear a filedescriptor
|
|
||||||
* with value 0:
|
|
||||||
*
|
|
||||||
* ctr_fds:
|
|
||||||
* ctr_fds[0] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
|
|
||||||
* ctr_fds[1] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
|
|
||||||
* ...
|
|
||||||
* ctr_fds[ALL_COUNTER-1] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
|
|
||||||
*/
|
|
||||||
static int *ctr_fds[ALL_COUNTER];
|
|
||||||
|
|
||||||
static int ecc_supported;
|
struct percpucounter {
|
||||||
|
int ctr_fds[ALL_COUNTER];
|
||||||
|
int pai_user[NUM_PAI_USER];
|
||||||
|
int pai_kernel[NUM_PAI_KERNEL];
|
||||||
|
unsigned int cpunum;
|
||||||
|
struct percpucounter *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct percpucounter *root;
|
||||||
|
pthread_mutex_t rootmux = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static volatile int hotplugdetected;
|
||||||
|
static unsigned int enabledcounter;
|
||||||
|
pthread_t hotplugthread;
|
||||||
|
|
||||||
|
#define foreachcpu(PCPU) if (pthread_mutex_lock(&rootmux)) return -1; \
|
||||||
|
for ((PCPU) = root; (PCPU) != NULL; (PCPU) = (PCPU)->next)
|
||||||
|
#define endforeachcpu() pthread_mutex_unlock(&rootmux)
|
||||||
|
|
||||||
|
static int ctr_state[NUM_COUNTER];
|
||||||
|
|
||||||
|
static volatile int stoprequested;
|
||||||
|
|
||||||
|
static int paipmutype, paipmueventstart;
|
||||||
|
|
||||||
|
static struct percpucounter *allocpercpucounter(unsigned int cpunum)
|
||||||
|
{
|
||||||
|
struct percpucounter *ppc;
|
||||||
|
|
||||||
|
ppc = malloc(sizeof(struct percpucounter));
|
||||||
|
if (ppc) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ALL_COUNTER; ++i)
|
||||||
|
ppc->ctr_fds[i] = -1;
|
||||||
|
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||||
|
ppc->pai_user[i] = -1;
|
||||||
|
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||||
|
ppc->pai_kernel[i] = -1;
|
||||||
|
ppc->cpunum = cpunum;
|
||||||
|
ppc->next = NULL;
|
||||||
|
}
|
||||||
|
return ppc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freepercpucounter(struct percpucounter *pcpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ALL_COUNTER; ++i)
|
||||||
|
(void)close(pcpu->ctr_fds[i]);
|
||||||
|
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||||
|
(void)close(pcpu->pai_user[i]);
|
||||||
|
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||||
|
(void)close(pcpu->pai_kernel[i]);
|
||||||
|
free(pcpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct percpucounter *findcpu(unsigned int cpunum, int unlinkflag)
|
||||||
|
{
|
||||||
|
struct percpucounter **prev = &root, *walk = root;
|
||||||
|
|
||||||
|
while (walk) {
|
||||||
|
if (walk->cpunum == cpunum) {
|
||||||
|
if (unlinkflag)
|
||||||
|
*prev = walk->next;
|
||||||
|
return walk;
|
||||||
|
}
|
||||||
|
prev = &(walk->next);
|
||||||
|
walk = walk->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
|
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
|
||||||
int cpu, int group_fd, unsigned long flags)
|
int cpu, int group_fd, unsigned long flags)
|
||||||
@@ -85,12 +150,43 @@ static int perf_counter_supported(const char *pmu, const char *counter)
|
|||||||
return !access(buf, R_OK);
|
return !access(buf, R_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int perf_event_encode(struct perf_event_attr *attr,
|
static int cpumf_authorized(void)
|
||||||
|
{
|
||||||
|
unsigned vermin, vermax, auth;
|
||||||
|
int res = 0, found = 0;
|
||||||
|
size_t linesize = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen("/proc/service_levels", "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
eprint("Failed to open /proc/service_levels (%d:%s)\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (getline(&line, &linesize, f) >= 0) {
|
||||||
|
if (sscanf(line,
|
||||||
|
"CPU-MF: Counter facility: version=%d.%d authorization=%x",
|
||||||
|
&vermin, &vermax, &auth) == 3) {
|
||||||
|
if (auth & 0x8)
|
||||||
|
res = 1;
|
||||||
|
else
|
||||||
|
eprint("CPU-MF counters not authorized.\n");
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
eprint("CPU-MF counters not available.\n");
|
||||||
|
free(line);
|
||||||
|
fclose(f);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perf_event_encode(int *pmutype, int *eventid,
|
||||||
const char *pmu, const char *event)
|
const char *pmu, const char *event)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int eventid;
|
|
||||||
int pmutype;
|
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/events/%s",
|
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/events/%s",
|
||||||
@@ -104,7 +200,7 @@ static int perf_event_encode(struct perf_event_attr *attr,
|
|||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fscanf(f, "event=0x%x\n", &eventid) != 1) {
|
if (fscanf(f, "event=0x%x\n", eventid) != 1) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
eprint("Event file %s has invalid format\n", buf);
|
eprint("Event file %s has invalid format\n", buf);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -121,21 +217,257 @@ static int perf_event_encode(struct perf_event_attr *attr,
|
|||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fscanf(f, "%d\n", &pmutype) != 1) {
|
if (fscanf(f, "%d\n", pmutype) != 1) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
eprint("Type file %s has invalid format\n", buf);
|
eprint("Type file %s has invalid format\n", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
attr->type = pmutype;
|
|
||||||
attr->config = eventid;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int activatecpu(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct perf_event_attr pfm_event;
|
||||||
|
struct percpucounter *ppc;
|
||||||
|
int fd, i, rc = 0;
|
||||||
|
|
||||||
|
ppc = allocpercpucounter(cpu);
|
||||||
|
if (ppc == NULL) {
|
||||||
|
eprint("Failed to allocate per cpu counter data");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pthread_mutex_lock(&rootmux)) {
|
||||||
|
freepercpucounter(ppc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* activate CPU-MF */
|
||||||
|
for (i = 0; i < ALL_COUNTER; ++i) {
|
||||||
|
if (ctr_state[i] == UNSUPPORTED)
|
||||||
|
continue;
|
||||||
|
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||||
|
pfm_event.size = sizeof(pfm_event);
|
||||||
|
pfm_event.type = pmf_counter_data[i].pmutype;
|
||||||
|
pfm_event.config = pmf_counter_data[i].eventid;
|
||||||
|
|
||||||
|
/* fetch file descriptor for this perf event
|
||||||
|
* the counter event should start disabled
|
||||||
|
*/
|
||||||
|
pfm_event.disabled = ctr_state[i] == DISABLED;
|
||||||
|
fd = perf_event_open(
|
||||||
|
&pfm_event,
|
||||||
|
-1, /* pid -1 means all processes */
|
||||||
|
cpu,
|
||||||
|
-1, /* group filedescriptor */
|
||||||
|
0); /* flags */
|
||||||
|
if (fd < 0) {
|
||||||
|
eprint("Perf_event_open() failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
ctr_state[i] = UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
ppc->ctr_fds[i] = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* activate pai_user and pai_kernel */
|
||||||
|
/* invariant:
|
||||||
|
(ctr_state[PAI_USER] == UNSUPPORTED) ==
|
||||||
|
(ctr_state[PAI_KERNEL] == UNSUPPORTED) */
|
||||||
|
if (ctr_state[PAI_USER] != UNSUPPORTED) {
|
||||||
|
for (i = 1; i <= NUM_PAI_USER; ++i) {
|
||||||
|
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||||
|
pfm_event.size = sizeof(pfm_event);
|
||||||
|
pfm_event.type = paipmutype;
|
||||||
|
pfm_event.config = paipmueventstart + i;
|
||||||
|
pfm_event.exclude_kernel = 1;
|
||||||
|
pfm_event.exclude_user = 0;
|
||||||
|
pfm_event.disabled = ctr_state[PAI_USER] == DISABLED;
|
||||||
|
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
eprint("Perf_event_open() failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
ctr_state[PAI_USER] = UNSUPPORTED;
|
||||||
|
ctr_state[PAI_KERNEL] = UNSUPPORTED;
|
||||||
|
goto outevents;
|
||||||
|
} else {
|
||||||
|
ppc->pai_user[i - 1] = fd;
|
||||||
|
}
|
||||||
|
pfm_event.exclude_kernel = 0;
|
||||||
|
pfm_event.exclude_user = 1;
|
||||||
|
pfm_event.disabled = ctr_state[PAI_KERNEL] == DISABLED;
|
||||||
|
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
eprint("Perf_event_open() failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
ctr_state[PAI_USER] = UNSUPPORTED;
|
||||||
|
ctr_state[PAI_KERNEL] = UNSUPPORTED;
|
||||||
|
goto outevents;
|
||||||
|
} else {
|
||||||
|
ppc->pai_kernel[i - 1] = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; i <= NUM_PAI_KERNEL; ++i) {
|
||||||
|
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||||
|
pfm_event.size = sizeof(pfm_event);
|
||||||
|
pfm_event.type = paipmutype;
|
||||||
|
pfm_event.config = paipmueventstart + i;
|
||||||
|
pfm_event.exclude_kernel = 0;
|
||||||
|
pfm_event.exclude_user = 1;
|
||||||
|
pfm_event.disabled = ctr_state[PAI_KERNEL] == DISABLED;
|
||||||
|
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
eprint("Perf_event_open() failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
ctr_state[PAI_USER] = UNSUPPORTED;
|
||||||
|
ctr_state[PAI_KERNEL] = UNSUPPORTED;
|
||||||
|
goto outevents;
|
||||||
|
} else {
|
||||||
|
ppc->pai_kernel[i - 1] = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outevents:
|
||||||
|
ppc->next = root;
|
||||||
|
root = ppc;
|
||||||
|
if (enabledcounter)
|
||||||
|
hotplugdetected = 1;
|
||||||
|
pthread_mutex_unlock(&rootmux);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deactivatecpu(unsigned int cpunum)
|
||||||
|
{
|
||||||
|
struct percpucounter *pcpu;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pthread_mutex_lock(&rootmux))
|
||||||
|
return;
|
||||||
|
pcpu = findcpu(cpunum, 1);
|
||||||
|
if (pcpu != NULL) {
|
||||||
|
for (i = 0; i < ALL_COUNTER; ++i)
|
||||||
|
(void)close(pcpu->ctr_fds[i]);
|
||||||
|
for (i = 0; i < NUM_PAI_USER; ++i)
|
||||||
|
(void)close(pcpu->pai_user[i]);
|
||||||
|
for (i = 0; i < NUM_PAI_KERNEL; ++i)
|
||||||
|
(void)close(pcpu->pai_kernel[i]);
|
||||||
|
free(pcpu);
|
||||||
|
if (enabledcounter)
|
||||||
|
hotplugdetected = 1;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&rootmux);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int addallcpus(void)
|
||||||
|
{
|
||||||
|
unsigned int start, end;
|
||||||
|
int scanned, rc = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
/* comma separated list of intervals */
|
||||||
|
if ((fp = fopen("/sys/devices/system/cpu/online", "r")) == NULL) {
|
||||||
|
eprint("Failed to get online cpus (%d:%s)\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!feof(fp)) {
|
||||||
|
/* scan all intervals of online cpus */
|
||||||
|
scanned = fscanf(fp, "%u-%u", &start, &end);
|
||||||
|
/* take care of singleton intervals */
|
||||||
|
if (scanned == 1)
|
||||||
|
end = start;
|
||||||
|
for (; start <= end; ++start) {
|
||||||
|
if (activatecpu(start)) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Skip comma separator */
|
||||||
|
(void)fgetc(fp);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
fclose(fp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perf_load_counter_data(void)
|
||||||
|
{
|
||||||
|
int i, res = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ALL_COUNTER; ++i) {
|
||||||
|
if (ctr_state[i] != UNSUPPORTED)
|
||||||
|
res |= perf_event_encode(&pmf_counter_data[i].pmutype,
|
||||||
|
&pmf_counter_data[i].eventid,
|
||||||
|
pmf_counter_name[i].pmu,
|
||||||
|
pmf_counter_name[i].pfm_name);
|
||||||
|
}
|
||||||
|
if (ctr_state[PAI_USER] != UNSUPPORTED)
|
||||||
|
res |= perf_event_encode(&paipmutype, &paipmueventstart,
|
||||||
|
"pai_crypto", "CRYPTO_ALL");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *hotplughandler(void *UNUSED(unused))
|
||||||
|
{
|
||||||
|
struct udev *hotplug;
|
||||||
|
struct udev_monitor *monitor;
|
||||||
|
struct pollfd item;
|
||||||
|
|
||||||
|
hotplug = udev_new();
|
||||||
|
if (!hotplug) {
|
||||||
|
eprint("Failed to create hotplug device\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
monitor = udev_monitor_new_from_netlink(hotplug, "udev");
|
||||||
|
udev_monitor_filter_add_match_subsystem_devtype(monitor, "cpu", NULL);
|
||||||
|
udev_monitor_enable_receiving(monitor);
|
||||||
|
item.fd = udev_monitor_get_fd(monitor);
|
||||||
|
item.events = POLLIN;
|
||||||
|
item.revents = 0;
|
||||||
|
while (!stoprequested) {
|
||||||
|
struct udev_device *dev;
|
||||||
|
const char *path, *action;
|
||||||
|
unsigned int cpunum;
|
||||||
|
int rc, on, off;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rc = poll(&item, 1, -1);
|
||||||
|
if (rc == -1) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dev = udev_monitor_receive_device(monitor);
|
||||||
|
if (dev == NULL)
|
||||||
|
continue;
|
||||||
|
action = udev_device_get_action(dev);
|
||||||
|
if (action == NULL)
|
||||||
|
continue;
|
||||||
|
off = strcmp(action, "offline") == 0;
|
||||||
|
on = strcmp(action, "online") == 0;
|
||||||
|
if (!on && !off)
|
||||||
|
continue;
|
||||||
|
path = udev_device_get_devpath(dev);
|
||||||
|
if (sscanf(path, "/devices/system/cpu/cpu%u", &cpunum) != 1)
|
||||||
|
continue;
|
||||||
|
if (on && activatecpu(cpunum))
|
||||||
|
eprint("Failed to attach to hotplugged CPU %u\n", cpunum);
|
||||||
|
if (off)
|
||||||
|
deactivatecpu(cpunum);
|
||||||
|
}
|
||||||
|
udev_monitor_unref(monitor);
|
||||||
|
udev_unref(hotplug);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int perf_init(void)
|
int perf_init(void)
|
||||||
{
|
{
|
||||||
int i, cpus, ctr, cpu, *fds;
|
int ecc_supported, i, num;
|
||||||
|
unsigned long maxfd;
|
||||||
memset(ctr_fds, 0, sizeof(ctr_fds));
|
struct rlimit rlim;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
/* initialize performance monitoring library */
|
/* initialize performance monitoring library */
|
||||||
if (!perf_supported()) {
|
if (!perf_supported()) {
|
||||||
@@ -143,99 +475,103 @@ int perf_init(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We currently support all cpumf counters plus two virtual
|
||||||
|
* counters for PAI. */
|
||||||
|
num = ALL_COUNTER + 2;
|
||||||
/* Check if ECC is supported on current hardware */
|
/* Check if ECC is supported on current hardware */
|
||||||
ecc_supported = perf_counter_supported("cpum_cf", "ECC_FUNCTION_COUNT");
|
ecc_supported = perf_counter_supported("cpum_cf", "ECC_FUNCTION_COUNT");
|
||||||
|
|
||||||
/* get number of logical processors */
|
if (!cpumf_authorized()) {
|
||||||
cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
for (i = 0; i < ALL_COUNTER; ++i)
|
||||||
|
ctr_state[i] = UNSUPPORTED;
|
||||||
/* for each counter */
|
num -= ALL_COUNTER;
|
||||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
} else if (!ecc_supported) {
|
||||||
|
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
|
||||||
/* Skip ECC counters completely if unsupported */
|
--num;
|
||||||
if (ctr == ECC_FUNCTIONS && !ecc_supported)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* allocate an array of ints to store for each CPU
|
|
||||||
* one filedescriptor + a terminating 0
|
|
||||||
*/
|
|
||||||
fds = (int *) calloc(sizeof(int), cpus+1);
|
|
||||||
if (!fds) {
|
|
||||||
eprint("Malloc() of %d byte failed, errno=%d [%s]\n",
|
|
||||||
(int)(sizeof(int) * (cpus+1)),
|
|
||||||
errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr_fds[ctr] = fds;
|
|
||||||
|
|
||||||
/* search for the counter's corresponding pfm name */
|
|
||||||
for (i = ALL_COUNTER-1; i >= 0; i--)
|
|
||||||
if ((int) pmf_counter_name[i].ctr == ctr)
|
|
||||||
break;
|
|
||||||
if (i < 0) {
|
|
||||||
eprint("Pfm ctr name not found for counter %d, please adjust pmf_counter_name[] in %s\n",
|
|
||||||
ctr, __FILE__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cpu = 0; cpu < cpus; cpu++) {
|
|
||||||
struct perf_event_attr pfm_event;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
memset(&pfm_event, 0, sizeof(pfm_event));
|
|
||||||
pfm_event.size = sizeof(pfm_event);
|
|
||||||
if (perf_event_encode(&pfm_event,
|
|
||||||
pmf_counter_name[i].pmu,
|
|
||||||
pmf_counter_name[i].pfm_name)) {
|
|
||||||
eprint("Failed to initialize counter %s for pmu %s\n",
|
|
||||||
pmf_counter_name[i].pfm_name,
|
|
||||||
pmf_counter_name[i].pmu);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fetch file descriptor for this perf event
|
|
||||||
* the counter event should start disabled
|
|
||||||
*/
|
|
||||||
pfm_event.disabled = 1;
|
|
||||||
fd = perf_event_open(
|
|
||||||
&pfm_event,
|
|
||||||
-1, /* pid -1 means all processes */
|
|
||||||
cpu,
|
|
||||||
-1, /* group filedescriptor */
|
|
||||||
0); /* flags */
|
|
||||||
if (fd < 0) {
|
|
||||||
eprint("Perf_event_open() failed with errno=%d [%s]\n",
|
|
||||||
errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fds[cpu] = fd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (!perf_counter_supported("pai_crypto", "CRYPTO_ALL")) {
|
||||||
|
ctr_state[PAI_USER] = UNSUPPORTED;
|
||||||
|
ctr_state[PAI_KERNEL] = UNSUPPORTED;
|
||||||
|
num -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
eprint("No crypto counters supported!\n");
|
||||||
|
|
||||||
|
if (perf_load_counter_data())
|
||||||
|
return -1;
|
||||||
|
/* We have to adjust the number of FDs possible since we might
|
||||||
|
* need more than 1024 (the typical soft limit) */
|
||||||
|
f = fopen("/proc/sys/fs/nr_open", "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
eprint("fopen failed for /proc/sys/fs/nr_open with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fscanf(f, "%lu", &maxfd) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
eprint("Failed to parse /proc/sys/fs/nr_open\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
rlim.rlim_cur = maxfd;
|
||||||
|
rlim.rlim_max = maxfd;
|
||||||
|
if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
|
||||||
|
eprint("setrlimit failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_create(&hotplugthread, NULL, hotplughandler, NULL)) {
|
||||||
|
eprint("Failed to start hotplug handler thread\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return addallcpus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void perf_stop(void)
|
||||||
|
{
|
||||||
|
stoprequested = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void perf_close(void)
|
void perf_close(void)
|
||||||
{
|
{
|
||||||
int ctr, *fds;
|
struct percpucounter *walk, *next;
|
||||||
|
|
||||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
pthread_kill(hotplugthread, SIGINT);
|
||||||
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
|
pthread_join(hotplugthread, NULL);
|
||||||
close(*fds);
|
walk = root;
|
||||||
*fds = 0;
|
while (walk) {
|
||||||
}
|
next = walk->next;
|
||||||
free(ctr_fds[ctr]);
|
freepercpucounter(walk);
|
||||||
ctr_fds[ctr] = NULL;
|
walk = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int enable_array(int *arr, int size)
|
||||||
|
{
|
||||||
|
int i, ec, rc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
ec = ioctl(arr[i], PERF_EVENT_IOC_ENABLE, 0);
|
||||||
|
if (ec < 0) {
|
||||||
|
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int perf_enable_ctr(enum ctr_e ctr)
|
int perf_enable_ctr(enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
int *fds, ec, rc = 0;
|
struct percpucounter *pcpu;
|
||||||
|
int ec, rc = 0;
|
||||||
|
|
||||||
if (ctr == ALL_COUNTER) {
|
if (ctr == ALL_COUNTER) {
|
||||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||||
@@ -243,24 +579,64 @@ int perf_enable_ctr(enum ctr_e ctr)
|
|||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (ctr < ALL_COUNTER) {
|
||||||
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
|
foreachcpu(pcpu) {
|
||||||
ec = ioctl(*fds, PERF_EVENT_IOC_ENABLE, 0);
|
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_ENABLE, 0);
|
||||||
if (ec < 0) {
|
if (ec < 0) {
|
||||||
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
|
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctr_state[ctr] = ENABLED;
|
||||||
|
++enabledcounter;
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_USER) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = enable_array(pcpu->pai_user, NUM_PAI_USER);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
ctr_state[ctr] = ENABLED;
|
||||||
|
++enabledcounter;
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_KERNEL) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = enable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
ctr_state[ctr] = ENABLED;
|
||||||
|
++enabledcounter;
|
||||||
|
endforeachcpu();
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int disable_array(int *arr, int size)
|
||||||
|
{
|
||||||
|
int i, ec, rc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
ec = ioctl(arr[i], PERF_EVENT_IOC_DISABLE, 0);
|
||||||
|
if (ec < 0) {
|
||||||
|
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int perf_disable_ctr(enum ctr_e ctr)
|
int perf_disable_ctr(enum ctr_e ctr)
|
||||||
{
|
{
|
||||||
int *fds, ec, rc = 0;
|
struct percpucounter *pcpu;
|
||||||
|
int ec, rc = 0;
|
||||||
|
|
||||||
if (ctr == ALL_COUNTER) {
|
if (ctr == ALL_COUNTER) {
|
||||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||||
@@ -268,70 +644,183 @@ int perf_disable_ctr(enum ctr_e ctr)
|
|||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (ctr < ALL_COUNTER) {
|
||||||
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
|
foreachcpu(pcpu) {
|
||||||
ec = ioctl(*fds, PERF_EVENT_IOC_DISABLE, 0);
|
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_DISABLE, 0);
|
||||||
if (ec < 0) {
|
if (ec < 0) {
|
||||||
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
|
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctr_state[ctr] = DISABLED;
|
||||||
|
--enabledcounter;
|
||||||
|
if (enabledcounter == 0)
|
||||||
|
hotplugdetected = 0;
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_USER) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = disable_array(pcpu->pai_user, NUM_PAI_USER);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
ctr_state[ctr] = DISABLED;
|
||||||
|
--enabledcounter;
|
||||||
|
if (enabledcounter == 0)
|
||||||
|
hotplugdetected = 0;
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_KERNEL) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = disable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
ctr_state[ctr] = DISABLED;
|
||||||
|
--enabledcounter;
|
||||||
|
if (enabledcounter == 0)
|
||||||
|
hotplugdetected = 0;
|
||||||
|
endforeachcpu();
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int perf_reset_ctr(enum ctr_e ctr)
|
static int reset_array(int *arr, int size)
|
||||||
{
|
{
|
||||||
int *fds, ec, rc = 0;
|
int ec, rc = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
ec = ioctl(arr[i], PERF_EVENT_IOC_RESET, 0);
|
||||||
|
if (ec < 0) {
|
||||||
|
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value)
|
||||||
|
{
|
||||||
|
struct percpucounter *pcpu;
|
||||||
|
int ec, rc = 0;
|
||||||
|
|
||||||
if (ctr == ALL_COUNTER) {
|
if (ctr == ALL_COUNTER) {
|
||||||
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
|
||||||
rc = perf_reset_ctr(ctr);
|
rc = perf_reset_ctr(ctr, value);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (ctr < ALL_COUNTER) {
|
||||||
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
|
foreachcpu(pcpu) {
|
||||||
ec = ioctl(*fds, PERF_EVENT_IOC_RESET, 0);
|
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_RESET, 0);
|
||||||
if (ec < 0) {
|
if (ec < 0) {
|
||||||
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
|
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_USER) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = reset_array(pcpu->pai_user, NUM_PAI_USER);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
endforeachcpu();
|
||||||
|
} else if (ctr == PAI_KERNEL) {
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
ec = reset_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
|
||||||
|
if (ec < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
endforeachcpu();
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
if (rc == 0)
|
||||||
|
rc = perf_read_ctr(ctr, value);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
|
int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
|
||||||
{
|
{
|
||||||
int *fds, ec, rc = -1;
|
struct percpucounter *pcpu;
|
||||||
|
int ec, rc = 0;
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (ctr == HOTPLUG_DETECTED) {
|
||||||
|
*value = hotplugdetected;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ctr == PAI_USER) {
|
||||||
|
*value = NUM_PAI_USER;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ctr == PAI_KERNEL) {
|
||||||
|
*value = NUM_PAI_KERNEL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ctr >= ALL_COUNTER)
|
||||||
|
return -1;
|
||||||
*value = 0;
|
*value = 0;
|
||||||
|
|
||||||
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
|
foreachcpu(pcpu) {
|
||||||
ec = read(*fds, &val, sizeof(val));
|
ec = read(pcpu->ctr_fds[ctr], &val, sizeof(val));
|
||||||
if (ec != sizeof(val)) {
|
if (ec != sizeof(val)) {
|
||||||
eprint("Read() on perf file descriptor failed with errno=%d [%s]\n",
|
eprint("Read() on perf file descriptor failed with errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
} else {
|
} else {
|
||||||
*value += val;
|
*value += val;
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
endforeachcpu();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int perf_ecc_supported(void)
|
int perf_ecc_supported(void)
|
||||||
{
|
{
|
||||||
return ecc_supported;
|
return ctr_state[ECC_FUNCTIONS] != UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_ctr_state(enum ctr_e ctr) {
|
||||||
|
if (ctr < NUM_COUNTER)
|
||||||
|
return ctr_state[ctr];
|
||||||
|
return UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value)
|
||||||
|
{
|
||||||
|
struct percpucounter *pcpu;
|
||||||
|
unsigned int maxctr;
|
||||||
|
int *arr, ec, rc = 0;
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
*value = 0;
|
||||||
|
maxctr = user ? NUM_PAI_USER : NUM_PAI_KERNEL;
|
||||||
|
if (ctrnum >= maxctr)
|
||||||
|
return -1;
|
||||||
|
foreachcpu(pcpu) {
|
||||||
|
arr = user ? pcpu->pai_user : pcpu->pai_kernel;
|
||||||
|
ec = read(arr[ctrnum], &val, sizeof(val));
|
||||||
|
if (ec != sizeof(val)) {
|
||||||
|
eprint("Read() on perf file descriptor failed with errno=%d [%s]\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
rc = -1;
|
||||||
|
} else {
|
||||||
|
*value += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endforeachcpu();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* basic socket and receive/send functions
|
* basic socket and receive/send functions
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2015, 2017
|
* Copyright IBM Corp. 2015, 2022
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -148,7 +149,51 @@ static int __read(int fd, void *buf, int buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int send_msg(int sfd, struct msg *m)
|
static int __timedwrite(int fd, const void *buf, int buflen, int timeout)
|
||||||
|
{
|
||||||
|
struct pollfd pfd = { .fd = fd, .events = POLLOUT };
|
||||||
|
int i = 0, n;
|
||||||
|
|
||||||
|
while (poll(&pfd, 1, timeout) == 1) {
|
||||||
|
n = write(fd, buf + i, buflen - i);
|
||||||
|
if (n < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return n;
|
||||||
|
} else if (n == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i += n;
|
||||||
|
if (buflen == i)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __timedread(int fd, void *buf, int buflen, int timeout)
|
||||||
|
{
|
||||||
|
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
||||||
|
int i = 0, n;
|
||||||
|
|
||||||
|
while (poll(&pfd, 1, timeout) == 1) {
|
||||||
|
n = read(fd, buf + i, buflen - i);
|
||||||
|
if (n < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return n;
|
||||||
|
} else if (n == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i += n;
|
||||||
|
if (buflen == i)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_msg(int sfd, struct msg *m, int timeout)
|
||||||
{
|
{
|
||||||
int n, len;
|
int n, len;
|
||||||
|
|
||||||
@@ -166,7 +211,7 @@ int send_msg(int sfd, struct msg *m)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = __write(sfd, m, len);
|
n = timeout ? __timedwrite(sfd, m, len, timeout) : __write(sfd, m, len);
|
||||||
if (n != len) {
|
if (n != len) {
|
||||||
eprint("Write() error: write()=%d expected %d, errno=%d [%s]\n",
|
eprint("Write() error: write()=%d expected %d, errno=%d [%s]\n",
|
||||||
n, len, errno, strerror(errno));
|
n, len, errno, strerror(errno));
|
||||||
@@ -176,12 +221,12 @@ int send_msg(int sfd, struct msg *m)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int recv_msg(int sfd, struct msg *m)
|
int recv_msg(int sfd, struct msg *m, int timeout)
|
||||||
{
|
{
|
||||||
int n, len;
|
int n, len;
|
||||||
|
|
||||||
len = sizeof(m->head);
|
len = sizeof(m->head);
|
||||||
n = __read(sfd, m, len);
|
n = timeout ? __timedread(sfd, m, len, timeout) : __read(sfd, m, len);
|
||||||
if (n != len) {
|
if (n != len) {
|
||||||
eprint("Recv() error: read()=%d expected %d, errno=%d [%s]\n",
|
eprint("Recv() error: read()=%d expected %d, errno=%d [%s]\n",
|
||||||
n, len, errno, strerror(errno));
|
n, len, errno, strerror(errno));
|
||||||
@@ -200,7 +245,8 @@ int recv_msg(int sfd, struct msg *m)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = __read(sfd, ((char *)m) + sizeof(m->head), len);
|
n = timeout ? __timedread(sfd, ((char *)m) + sizeof(m->head), len, timeout) :
|
||||||
|
__read(sfd, ((char *)m) + sizeof(m->head), len);
|
||||||
if (n != len) {
|
if (n != len) {
|
||||||
eprint("Recv() error: recv()=%d expected %d, errno=%d [%s]\n",
|
eprint("Recv() error: recv()=%d expected %d, errno=%d [%s]\n",
|
||||||
n, len, errno, strerror(errno));
|
n, len, errno, strerror(errno));
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "lib/util_arch.h"
|
#include "lib/util_arch.h"
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
|
#include "lib/util_path.h"
|
||||||
#include "lib/util_prg.h"
|
#include "lib/util_prg.h"
|
||||||
|
|
||||||
#include "lib/libcpumf.h"
|
#include "lib/libcpumf.h"
|
||||||
@@ -3318,17 +3319,18 @@ static void show_info(struct cpumf_info *p, int details)
|
|||||||
* counter was renamed from CCERROR to CCFINISH in linux version 5.8.
|
* counter was renamed from CCERROR to CCFINISH in linux version 5.8.
|
||||||
* Check for existence of file /sys/devices/cpum_cf/events/DLFT_CCERROR.
|
* Check for existence of file /sys/devices/cpum_cf/events/DLFT_CCERROR.
|
||||||
*/
|
*/
|
||||||
#define CCERROR "/sys/devices/cpum_cf/events/DFLT_CCERROR"
|
|
||||||
static void read_ccerror(struct counters *cp, size_t cp_cnt)
|
static void read_ccerror(struct counters *cp, size_t cp_cnt)
|
||||||
{
|
{
|
||||||
|
char *ctrname, *path;
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
char *ctrname;
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (!stat(CCERROR, &sbuf))
|
path = util_path_sysfs("devices/cpum_cf/events/DFLT_CCERROR");
|
||||||
|
if (!stat(path, &sbuf))
|
||||||
ctrname = "DFLT_CCERROR";
|
ctrname = "DFLT_CCERROR";
|
||||||
else
|
else
|
||||||
ctrname = "DFLT_CCFINISH";
|
ctrname = "DFLT_CCFINISH";
|
||||||
|
free(path);
|
||||||
/* Find DFLT_CC{FINISH,ERROR} in table and set name */
|
/* Find DFLT_CC{FINISH,ERROR} in table and set name */
|
||||||
for (struct counters *p = cp; i < cp_cnt; ++i, ++p)
|
for (struct counters *p = cp; i < cp_cnt; ++i, ++p)
|
||||||
if (p->ctrnum == 265) {
|
if (p->ctrnum == 265) {
|
||||||
|
|||||||
@@ -276,9 +276,7 @@ static bool check_setpossible(void)
|
|||||||
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
|
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
|
||||||
return false;
|
return false;
|
||||||
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
|
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
|
||||||
check = calloc(max_possible_cpus, sizeof(*check));
|
check = util_zalloc(max_possible_cpus * sizeof(*check));
|
||||||
if (!check)
|
|
||||||
err(EXIT_FAILURE, "Maximum CPUs %u", max_possible_cpus);
|
|
||||||
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
|
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
|
||||||
free(check);
|
free(check);
|
||||||
return false;
|
return false;
|
||||||
@@ -356,6 +354,8 @@ static void line(char *header)
|
|||||||
putchar(',');
|
putchar(',');
|
||||||
printf("%ld", ctrname[i].total);
|
printf("%ld", ctrname[i].total);
|
||||||
comma = true;
|
comma = true;
|
||||||
|
ctrname[i].total = 0;
|
||||||
|
ctrname[i].hitcnt = false;
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
@@ -446,7 +446,7 @@ static bool add_countervalue(size_t idx, unsigned int cpu, unsigned long value)
|
|||||||
ctrname[idx].ccv = calloc(max_possible_cpus,
|
ctrname[idx].ccv = calloc(max_possible_cpus,
|
||||||
sizeof(unsigned long));
|
sizeof(unsigned long));
|
||||||
if (ctrname[idx].ccv)
|
if (ctrname[idx].ccv)
|
||||||
ctrname[idx].ccv[cpu] += value;
|
ctrname[idx].ccv[cpu] = value;
|
||||||
ctrname[idx].total += value;
|
ctrname[idx].total += value;
|
||||||
ctrname[idx].hitcnt = true;
|
ctrname[idx].hitcnt = true;
|
||||||
return true;
|
return true;
|
||||||
@@ -458,10 +458,8 @@ static int test_read(struct s390_hwctr_read *read)
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
/* Clear previous hit counters */
|
/* Clear previous hit counters */
|
||||||
for (unsigned int i = 0; i < max_possible_cpus; ++i) {
|
for (unsigned int i = 0; i < max_possible_cpus; ++i)
|
||||||
check[i].sets_hit = 0;
|
|
||||||
check[i].cpu_hit = false;
|
check[i].cpu_hit = false;
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate over all CPUs */
|
/* Iterate over all CPUs */
|
||||||
for (unsigned int i = 0; i < read->no_cpus; ++i) {
|
for (unsigned int i = 0; i < read->no_cpus; ++i) {
|
||||||
@@ -533,13 +531,8 @@ static int do_read(int ioctlfd)
|
|||||||
struct s390_hwctr_read *read;
|
struct s390_hwctr_read *read;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!ioctlbuffer) {
|
if (!ioctlbuffer)
|
||||||
ioctlbuffer = malloc(ioctlbuffer_len);
|
ioctlbuffer = util_malloc(ioctlbuffer_len);
|
||||||
if (!ioctlbuffer) {
|
|
||||||
warn("ioctl S390_HWCTR_START");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read = (struct s390_hwctr_read *)ioctlbuffer;
|
read = (struct s390_hwctr_read *)ioctlbuffer;
|
||||||
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
|
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
|
|||||||
@@ -88,12 +88,6 @@ Include the MT_Diagnostic counter set.
|
|||||||
Include the problem counter set.
|
Include the problem counter set.
|
||||||
.IP a
|
.IP a
|
||||||
Include all known counter sets (default).
|
Include all known counter sets (default).
|
||||||
.SH "Concurrency with perf tool"
|
|
||||||
The \*c tool and the linux
|
|
||||||
.B perf
|
|
||||||
tool use the same hardware and cannot be used concurrently.
|
|
||||||
Both tools print an error message and abort when they
|
|
||||||
detect this situation.
|
|
||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
The first example enables the basic and problem counter sets on CPU 0 and 1.
|
The first example enables the basic and problem counter sets on CPU 0 and 1.
|
||||||
Two read operations are performed and a summary line is printed for each
|
Two read operations are performed and a summary line is printed for each
|
||||||
|
|||||||
68
cpumf/pai.c
68
cpumf/pai.c
@@ -32,6 +32,7 @@
|
|||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_file.h"
|
||||||
#include "lib/util_libc.h"
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_list.h"
|
#include "lib/util_list.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
@@ -56,6 +57,7 @@ static cpu_set_t cpu_online_mask;
|
|||||||
static int verbose, humantime;
|
static int verbose, humantime;
|
||||||
static struct util_list list_pai_event;
|
static struct util_list list_pai_event;
|
||||||
static struct util_list list_pmu_event;
|
static struct util_list list_pmu_event;
|
||||||
|
static bool summary;
|
||||||
|
|
||||||
/* System call to perf_event_open(2) */
|
/* System call to perf_event_open(2) */
|
||||||
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
|
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
|
||||||
@@ -114,7 +116,7 @@ static void ev_alloc(int enr, int cpu, int flags)
|
|||||||
warnx("NNPA does not support kernel/user space selector");
|
warnx("NNPA does not support kernel/user space selector");
|
||||||
flags &= ~as;
|
flags &= ~as;
|
||||||
}
|
}
|
||||||
event->attr.type = libcpumf_pmutype(S390_SYSFS_PAI_NNPA);
|
event->attr.type = libcpumf_pmutype(S390_SYSFS_PAI_EXT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
event->attr.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_CPU |
|
event->attr.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_CPU |
|
||||||
@@ -263,9 +265,11 @@ static int savemap(int fd, void *data, struct data_pos *dp)
|
|||||||
int wrapped;
|
int wrapped;
|
||||||
|
|
||||||
d_head_old = d_head;
|
d_head_old = d_head;
|
||||||
printf("Data head:%#llx tail:%#llx offset:%#llx size:%#llx\n",
|
if (verbose) {
|
||||||
dp->data_head, dp->data_tail, dp->data_offset,
|
printf("Data head:%#llx tail:%#llx offset:%#llx size:%#llx\n",
|
||||||
dp->data_size);
|
dp->data_head, dp->data_tail, dp->data_offset,
|
||||||
|
dp->data_size);
|
||||||
|
}
|
||||||
if (!diff)
|
if (!diff)
|
||||||
return 0;
|
return 0;
|
||||||
wrapped = d_head / dp->data_size != d_prev / dp->data_size;
|
wrapped = d_head / dp->data_size != d_prev / dp->data_size;
|
||||||
@@ -280,13 +284,16 @@ static int savemap(int fd, void *data, struct data_pos *dp)
|
|||||||
int part2 = dp->data_size - d_prev;
|
int part2 = dp->data_size - d_prev;
|
||||||
|
|
||||||
diff -= part2;
|
diff -= part2;
|
||||||
printf("Write %d bytes [%ld,%lld)\n", part2, d_prev,
|
if (verbose) {
|
||||||
dp->data_size);
|
printf("Write %d bytes [%ld,%lld)\n", part2, d_prev,
|
||||||
|
dp->data_size);
|
||||||
|
}
|
||||||
if (write(fd, data + d_prev, part2) == -1)
|
if (write(fd, data + d_prev, part2) == -1)
|
||||||
err(EXIT_FAILURE, "write error for event file");
|
err(EXIT_FAILURE, "write error for event file");
|
||||||
d_prev = 0; /* Start at position zero */
|
d_prev = 0; /* Start at position zero */
|
||||||
}
|
}
|
||||||
printf("Write %d bytes [%ld,%ld)\n", diff, d_prev, d_head);
|
if (verbose)
|
||||||
|
printf("Write %d bytes [%ld,%ld)\n", diff, d_prev, d_head);
|
||||||
if (write(fd, data + d_prev, diff) == -1)
|
if (write(fd, data + d_prev, diff) == -1)
|
||||||
err(EXIT_FAILURE, "write error for event file");
|
err(EXIT_FAILURE, "write error for event file");
|
||||||
|
|
||||||
@@ -299,7 +306,10 @@ static void readmap(int fd)
|
|||||||
struct pai_event *p = perffd_2_event(fd);
|
struct pai_event *p = perffd_2_event(fd);
|
||||||
struct perf_event_mmap_page *area;
|
struct perf_event_mmap_page *area;
|
||||||
|
|
||||||
printf("Ring buffer for fd %d %s(%d)\n", fd, p->file_name, p->file_fd);
|
if (verbose) {
|
||||||
|
printf("Ring buffer for fd %d %s(%d)\n", fd, p->file_name,
|
||||||
|
p->file_fd);
|
||||||
|
}
|
||||||
area = p->map_addr;
|
area = p->map_addr;
|
||||||
savemap(p->file_fd, p->map_addr + area->data_offset,
|
savemap(p->file_fd, p->map_addr + area->data_offset,
|
||||||
(struct data_pos *)&area->data_head);
|
(struct data_pos *)&area->data_head);
|
||||||
@@ -383,7 +393,10 @@ static int evtraw_show(__u64 evtnum, unsigned char *p)
|
|||||||
offset += sizeof(ctr);
|
offset += sizeof(ctr);
|
||||||
value = *(__u64 *)(p + offset);
|
value = *(__u64 *)(p + offset);
|
||||||
offset += sizeof(value);
|
offset += sizeof(value);
|
||||||
printf("%c%hd:%#llx", offset > 14 ? ',' : ' ', ctr, value);
|
if (!summary) {
|
||||||
|
printf("%c%hd:%#llx", offset > 14 ? ',' : ' ', ctr,
|
||||||
|
value);
|
||||||
|
}
|
||||||
lookup_event(evtnum, ctr, value);
|
lookup_event(evtnum, ctr, value);
|
||||||
if (offset + sizeof(ctr) + sizeof(value) > bytes)
|
if (offset + sizeof(ctr) + sizeof(value) > bytes)
|
||||||
break;
|
break;
|
||||||
@@ -412,6 +425,12 @@ static const char *evt_selector(struct perf_event_attr *pa)
|
|||||||
|
|
||||||
static void evt_show(__u64 evtnum, const char *evtsel, struct pai_event_out *ev)
|
static void evt_show(__u64 evtnum, const char *evtsel, struct pai_event_out *ev)
|
||||||
{
|
{
|
||||||
|
if (summary) {
|
||||||
|
if (ev->type == PERF_RECORD_SAMPLE && ev->raw)
|
||||||
|
evtraw_show(evtnum, ev->raw);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
timestamp(ev->time);
|
timestamp(ev->time);
|
||||||
printf("%d ", ev->cpu);
|
printf("%d ", ev->cpu);
|
||||||
|
|
||||||
@@ -633,30 +652,13 @@ bypass:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read perf_event_open() config value for event. */
|
|
||||||
static int read_event(char *dirname, char *filename)
|
|
||||||
{
|
|
||||||
int config, rc = 0;
|
|
||||||
char *pathname;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
util_asprintf(&pathname, "%s/%s", dirname, filename);
|
|
||||||
fp = fopen(pathname, "r");
|
|
||||||
if (fp) {
|
|
||||||
rc = fscanf(fp, "event=%x", &config);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
free(pathname);
|
|
||||||
return rc == 1 ? config : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan event directory and fill event list. */
|
/* Scan event directory and fill event list. */
|
||||||
static int scan_events(struct pmu_events *p)
|
static int scan_events(struct pmu_events *p)
|
||||||
{
|
{
|
||||||
|
char *evtname, *evtdir, *path;
|
||||||
struct dirent **de_vec;
|
struct dirent **de_vec;
|
||||||
struct event_name *ep;
|
struct event_name *ep;
|
||||||
char *evtdir, *path;
|
int evtnr, count, rc;
|
||||||
int count, rc;
|
|
||||||
|
|
||||||
path = util_path_sysfs("devices");
|
path = util_path_sysfs("devices");
|
||||||
rc = util_asprintf(&evtdir, "%s/%s/events", path, p->name);
|
rc = util_asprintf(&evtdir, "%s/%s/events", path, p->name);
|
||||||
@@ -677,8 +679,10 @@ static int scan_events(struct pmu_events *p)
|
|||||||
if (de_vec[i]->d_type == DT_DIR)
|
if (de_vec[i]->d_type == DT_DIR)
|
||||||
continue;
|
continue;
|
||||||
ep->name = util_strdup(de_vec[i]->d_name);
|
ep->name = util_strdup(de_vec[i]->d_name);
|
||||||
rc = read_event(evtdir, de_vec[i]->d_name);
|
util_asprintf(&evtname, "%s/%s", evtdir, de_vec[i]->d_name);
|
||||||
if (rc == -1 || !ep->name) {
|
rc = util_file_read_va(evtname, "event=%x", &evtnr);
|
||||||
|
free(evtname);
|
||||||
|
if (rc != 1) {
|
||||||
for (ep = p->lst, rc = 0; rc < p->lstlen; ++rc, ++ep)
|
for (ep = p->lst, rc = 0; rc < p->lstlen; ++rc, ++ep)
|
||||||
free(ep->name);
|
free(ep->name);
|
||||||
free(p->lst);
|
free(p->lst);
|
||||||
@@ -686,7 +690,7 @@ static int scan_events(struct pmu_events *p)
|
|||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ep->config = rc;
|
ep->config = evtnr;
|
||||||
if (p->base > ep->config)
|
if (p->base > ep->config)
|
||||||
p->base = ep->config;
|
p->base = ep->config;
|
||||||
++p->lstlen;
|
++p->lstlen;
|
||||||
@@ -1005,7 +1009,7 @@ static unsigned long check_mapsize(unsigned long n)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool crypto_record = false, report = false, summary = false;
|
bool crypto_record = false, report = false;
|
||||||
bool nnpa_record = false;
|
bool nnpa_record = false;
|
||||||
unsigned long loop_count = 1;
|
unsigned long loop_count = 1;
|
||||||
int ch, group = 0;
|
int ch, group = 0;
|
||||||
|
|||||||
@@ -118,12 +118,17 @@ Specify the \fImode\fR to be used to format the device. Valid modes are:
|
|||||||
.IP full
|
.IP full
|
||||||
Format the entire disk with the specified blocksize. (default)
|
Format the entire disk with the specified blocksize. (default)
|
||||||
.IP quick
|
.IP quick
|
||||||
Format the first two tracks and write label and partition information. Only use
|
Format the first two tracks and write label and partition information. Use this
|
||||||
this option if you are sure that the target DASD already contains a regular
|
option only if you are sure that the target DASD already contains a regular
|
||||||
format with the specified blocksize. A blocksize can optionally be specified
|
format with the specified blocksize. A blocksize can optionally be specified
|
||||||
using \fB-b\fR (\fB--blocksize\fR).
|
using \fB-b\fR (\fB--blocksize\fR).
|
||||||
.br
|
.br
|
||||||
For thin-provisioned DASD ESE volumes this is the default mode.
|
For thin-provisioned DASD ESE volumes, quick is the default mode. A full space
|
||||||
|
release then precedes the formatting step. If this space release fails, dasdfmt
|
||||||
|
falls back to a full-format mode. Formatting stops if the space release fails
|
||||||
|
and quick mode was specified explicitly using \fB-M\fR. Specify the
|
||||||
|
\fB--no-discard\fR option to omit the space release.
|
||||||
|
|
||||||
.IP expand
|
.IP expand
|
||||||
Format all unformatted tracks at the end of the target DASD. This mode assumes
|
Format all unformatted tracks at the end of the target DASD. This mode assumes
|
||||||
that tracks at the beginning of the DASD volume have already been correctly
|
that tracks at the beginning of the DASD volume have already been correctly
|
||||||
|
|||||||
@@ -1107,8 +1107,8 @@ static void dasdfmt_write_labels(volume_label_t *vlabel,
|
|||||||
} else {
|
} else {
|
||||||
vlabel->ldl_version = 0xf2; /* EBCDIC '2' */
|
vlabel->ldl_version = 0xf2; /* EBCDIC '2' */
|
||||||
vlabel->formatted_blocks = cylinders * heads * geo.sectors;
|
vlabel->formatted_blocks = cylinders * heads * geo.sectors;
|
||||||
rc = write(fd, &vlabel->vollbl, (sizeof(*vlabel)
|
rc = write(fd, (void *)vlabel + sizeof(vlabel->volkey),
|
||||||
- sizeof(vlabel->volkey)));
|
(sizeof(*vlabel) - sizeof(vlabel->volkey)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((rc != sizeof(*vlabel) - sizeof(vlabel->formatted_blocks)) &&
|
if (((rc != sizeof(*vlabel) - sizeof(vlabel->formatted_blocks)) &&
|
||||||
@@ -1230,7 +1230,7 @@ static void dasdfmt_find_start(unsigned int cylinders, unsigned int heads,
|
|||||||
format_params->start_unit = first;
|
format_params->start_unit = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dasdfmt_release_space(void)
|
static int dasdfmt_release_space(void)
|
||||||
{
|
{
|
||||||
format_data_t r = {
|
format_data_t r = {
|
||||||
.start_unit = 0,
|
.start_unit = 0,
|
||||||
@@ -1240,12 +1240,21 @@ static void dasdfmt_release_space(void)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!g.ese || g.no_discard)
|
if (!g.ese || g.no_discard)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
printf("Releasing space for the entire device...\n");
|
printf("Releasing space for the entire device...\n");
|
||||||
err = dasd_release_space(g.dev_node, &r);
|
err = dasd_release_space(g.dev_node, &r);
|
||||||
if (err)
|
/*
|
||||||
|
* Warn or Error on failing RAS depending on QUICK mode set explicitly or automatically
|
||||||
|
*/
|
||||||
|
if (err && !g.mode_specified) {
|
||||||
|
warnx("Could not release space. Falling back to full format.");
|
||||||
|
return 1;
|
||||||
|
} else if (err && g.mode_specified) {
|
||||||
error("Could not release space: %s", strerror(err));
|
error("Could not release space: %s", strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dasdfmt_prepare_and_format(unsigned int cylinders, unsigned int heads,
|
static void dasdfmt_prepare_and_format(unsigned int cylinders, unsigned int heads,
|
||||||
@@ -1445,8 +1454,12 @@ static void do_format_dasd(volume_label_t *vlabel, format_data_t *p,
|
|||||||
dasdfmt_prepare_and_format(cylinders, heads, p);
|
dasdfmt_prepare_and_format(cylinders, heads, p);
|
||||||
break;
|
break;
|
||||||
case QUICK:
|
case QUICK:
|
||||||
dasdfmt_release_space();
|
if (dasdfmt_release_space()) {
|
||||||
dasdfmt_quick_format(cylinders, heads, p);
|
p->stop_unit = (cylinders * heads) - 1;
|
||||||
|
dasdfmt_prepare_and_format(cylinders, heads, p);
|
||||||
|
} else {
|
||||||
|
dasdfmt_quick_format(cylinders, heads, p);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EXPAND:
|
case EXPAND:
|
||||||
dasdfmt_expand_format(cylinders, heads, p);
|
dasdfmt_expand_format(cylinders, heads, p);
|
||||||
|
|||||||
@@ -16,13 +16,8 @@ check_dep:
|
|||||||
|
|
||||||
BUILDTARGET = check_dep
|
BUILDTARGET = check_dep
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
CURL_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||||
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
|
CURL_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||||
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
|
|
||||||
else
|
|
||||||
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
|
|
||||||
CURL_LDLIBS = -lcurl
|
|
||||||
endif # shell
|
|
||||||
|
|
||||||
endif # HAVE_CURL
|
endif # HAVE_CURL
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "lib/dasd_sys.h"
|
#include "lib/dasd_sys.h"
|
||||||
#include "lib/libzds.h"
|
#include "lib/libzds.h"
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
#include "lib/util_prg.h"
|
#include "lib/util_prg.h"
|
||||||
#include "lib/util_sys.h"
|
#include "lib/util_sys.h"
|
||||||
@@ -1788,10 +1789,8 @@ dasdview_print_format1(unsigned int size, unsigned char *dumpstr)
|
|||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if ((i / 16) * 16 == i) {
|
if ((i / 16) * 16 == i) {
|
||||||
printf("\n| ");
|
printf("\n| ");
|
||||||
strncpy(asc, (char *)dumpstr + i, 16);
|
util_strlcpy(asc, (char *)dumpstr + i, 16);
|
||||||
strncpy(ebc, (char *)dumpstr + i, 16);
|
util_strlcpy(ebc, (char *)dumpstr + i, 16);
|
||||||
asc[16] = '\0';
|
|
||||||
ebc[16] = '\0';
|
|
||||||
}
|
}
|
||||||
printf("%02X", dumpstr[i]);
|
printf("%02X", dumpstr[i]);
|
||||||
if (((i + 1) / 4) * 4 == i + 1)
|
if (((i + 1) / 4) * 4 == i + 1)
|
||||||
@@ -1822,8 +1821,8 @@ dasdview_print_format2(unsigned int size, unsigned char *dumpstr,
|
|||||||
begin + (unsigned long long)i,
|
begin + (unsigned long long)i,
|
||||||
begin + (unsigned long long)i);
|
begin + (unsigned long long)i);
|
||||||
|
|
||||||
strncpy(asc, (char *)dumpstr + i, 8);
|
util_strlcpy(asc, (char *)dumpstr + i, 8);
|
||||||
strncpy(ebc, (char *)dumpstr + i, 8);
|
util_strlcpy(ebc, (char *)dumpstr + i, 8);
|
||||||
}
|
}
|
||||||
printf("%02X", dumpstr[i]);
|
printf("%02X", dumpstr[i]);
|
||||||
if (((i + 1) / 4) * 4 == i + 1)
|
if (((i + 1) / 4) * 4 == i + 1)
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ all: all-recursive
|
|||||||
|
|
||||||
install: all install-recursive
|
install: all install-recursive
|
||||||
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)"
|
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)"
|
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
|
||||||
|
|
||||||
clean: clean-recursive
|
clean: clean-recursive
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
# Common definitions
|
# Common definitions
|
||||||
include ../../common.mak
|
include ../../common.mak
|
||||||
|
|
||||||
|
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
||||||
|
|
||||||
|
ifeq ($(HOST_ARCH),s390x)
|
||||||
ZIPL_DIR := $(rootdir)/zipl
|
ZIPL_DIR := $(rootdir)/zipl
|
||||||
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
||||||
|
PKGDATADIR := $(DESTDIR)$(TOOLS_DATADIR)/genprotimg
|
||||||
|
|
||||||
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
||||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
||||||
@@ -15,11 +19,9 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
|
|||||||
-fno-delete-null-pointer-checks -fno-stack-protector \
|
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||||
-Wall -Wformat-security -Wextra -Werror \
|
-Wall -Wformat-security -Wextra \
|
||||||
-Wno-array-bounds
|
-Wno-array-bounds
|
||||||
|
|
||||||
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
|
||||||
|
|
||||||
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
||||||
ZIPL_SRCS_ASM := entry.S
|
ZIPL_SRCS_ASM := entry.S
|
||||||
|
|
||||||
@@ -27,9 +29,6 @@ ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
|
|||||||
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
||||||
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
||||||
|
|
||||||
|
|
||||||
all: $(FILES)
|
|
||||||
|
|
||||||
# Prevent make from using some default rules...
|
# Prevent make from using some default rules...
|
||||||
%: %.S
|
%: %.S
|
||||||
|
|
||||||
@@ -69,29 +68,37 @@ endif
|
|||||||
|
|
||||||
stage3b_reloc.o: stage3b.bin
|
stage3b_reloc.o: stage3b.bin
|
||||||
|
|
||||||
stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS)
|
stage3a.elf: head.o stage3a_init.o $(ZIPL_OBJS)
|
||||||
stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS)
|
stage3b.elf: head.o $(ZIPL_OBJS)
|
||||||
stage3b_reloc.elf:
|
|
||||||
|
|
||||||
%.elf: %.o
|
%.elf: %.lds %.o
|
||||||
case $* in \
|
$(LINK) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,-T,$< -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
||||||
stage3a) SFLAGS="-Wl,-T,stage3a.lds";; \
|
|
||||||
stage3b) SFLAGS="-Wl,-T,stage3b.lds";; \
|
|
||||||
stage3b_reloc) SFLAGS="-Wl,-estage3b_reloc_start,-Ttext,0";; \
|
|
||||||
esac; \
|
|
||||||
$(LINK) $$SFLAGS $(NO_PIE_LDFLAGS) -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
|
||||||
@chmod a-x $@
|
@chmod a-x $@
|
||||||
|
|
||||||
%.bin: %.elf
|
%.bin: %.elf
|
||||||
$(OBJCOPY) -O binary \
|
$(OBJCOPY) -O binary $< $@
|
||||||
--only-section=.text* \
|
|
||||||
--only-section=.ex_table* \
|
|
||||||
--only-section=.fixup* \
|
|
||||||
--only-section=.data* \
|
|
||||||
--only-section=.rodata* \
|
|
||||||
$< $@
|
|
||||||
@chmod a-x $@
|
@chmod a-x $@
|
||||||
|
|
||||||
|
install: stage3a.bin stage3b_reloc.bin
|
||||||
|
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin "$(PKGDATADIR)"
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin "$(PKGDATADIR)"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Don't generate the dependency files (see `common.mak` for the
|
||||||
|
# `-include $(dependencies_c)` statement).
|
||||||
|
.PHONY: $(dependencies_c)
|
||||||
|
|
||||||
|
$(FILES):
|
||||||
|
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||||
|
|
||||||
|
install:
|
||||||
|
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := all
|
||||||
|
all: $(FILES)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
||||||
|
|
||||||
|
|||||||
@@ -29,3 +29,8 @@ _start:
|
|||||||
brasl %r14, initialize
|
brasl %r14, initialize
|
||||||
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
/* The code doesn't require an executable stack */
|
||||||
|
#if defined(__linux__) && defined(__ELF__)
|
||||||
|
.section .note.GNU-stack,"",%progbits
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "stage3a.h"
|
#include "stage3a.h"
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ ENTRY(_init)
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x0;
|
|
||||||
|
|
||||||
. = HEAP_ADDRESS;
|
. = HEAP_ADDRESS;
|
||||||
__heap_start = .;
|
__heap_start = .;
|
||||||
.heap : {
|
.heap : {
|
||||||
@@ -46,7 +44,7 @@ SECTIONS
|
|||||||
. = STAGE3A_INIT_ENTRY;
|
. = STAGE3A_INIT_ENTRY;
|
||||||
__text_init_start = .;
|
__text_init_start = .;
|
||||||
.text : {
|
.text : {
|
||||||
stage3a_init.o(.text.init)
|
*(.text.init)
|
||||||
__text_init_stop = ABSOLUTE(.);
|
__text_init_stop = ABSOLUTE(.);
|
||||||
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
|
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
|
||||||
* otherwise the text data could be overwritten by the original zipl stage3
|
* otherwise the text data could be overwritten by the original zipl stage3
|
||||||
@@ -56,8 +54,8 @@ SECTIONS
|
|||||||
. = 0x1000;
|
. = 0x1000;
|
||||||
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
|
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
|
||||||
"Text section doesn't conform to the described memory layout");
|
"Text section doesn't conform to the described memory layout");
|
||||||
head.o(.text.start)
|
*(.text.start)
|
||||||
*(.text)
|
*(.text .text.*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.ex_table ALIGN(16) : {
|
.ex_table ALIGN(16) : {
|
||||||
@@ -74,7 +72,7 @@ SECTIONS
|
|||||||
|
|
||||||
.rodata ALIGN(16) : {
|
.rodata ALIGN(16) : {
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata.*)
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data ALIGN(16) : {
|
.data ALIGN(16) : {
|
||||||
@@ -90,14 +88,10 @@ SECTIONS
|
|||||||
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
|
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List this explicitly as otherwise .note.gnu.build-id will be
|
|
||||||
* put at 0x0 */
|
|
||||||
.notes : {
|
|
||||||
*(.note.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sections to be discarded */
|
/* Sections to be discarded */
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
*(.interp)
|
||||||
|
*(.note.GNU-stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,8 @@ _init:
|
|||||||
br %r1
|
br %r1
|
||||||
.Lstage3a_entry: .long STAGE3A_ENTRY
|
.Lstage3a_entry: .long STAGE3A_ENTRY
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
/* The code doesn't require an executable stack */
|
||||||
|
#if defined(__linux__) && defined(__ELF__)
|
||||||
|
.section .note.GNU-stack,"",%progbits
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "stage3b.h"
|
#include "stage3b.h"
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/linux_layout.h"
|
#include "boot/linux_layout.h"
|
||||||
#include "boot/loaders_layout.h"
|
#include "boot/loaders_layout.h"
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
|
|
||||||
/* Must not have any padding included */
|
/* Must not have any padding included */
|
||||||
struct memblob {
|
struct memblob {
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ ENTRY(_start)
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x0;
|
|
||||||
|
|
||||||
. = HEAP_ADDRESS;
|
. = HEAP_ADDRESS;
|
||||||
__heap_start = .;
|
__heap_start = .;
|
||||||
.heap : {
|
.heap : {
|
||||||
@@ -34,8 +32,8 @@ SECTIONS
|
|||||||
|
|
||||||
. = STAGE3B_ENTRY;
|
. = STAGE3B_ENTRY;
|
||||||
.text : {
|
.text : {
|
||||||
head.o(.text.start)
|
*(.text.start)
|
||||||
*(.text)
|
*(.text .text.*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.ex_table ALIGN(16) : {
|
.ex_table ALIGN(16) : {
|
||||||
@@ -52,7 +50,7 @@ SECTIONS
|
|||||||
|
|
||||||
.rodata ALIGN(16) : {
|
.rodata ALIGN(16) : {
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata.*)
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data ALIGN(16) : {
|
.data ALIGN(16) : {
|
||||||
@@ -74,14 +72,12 @@ SECTIONS
|
|||||||
}
|
}
|
||||||
__stack_end = .;
|
__stack_end = .;
|
||||||
|
|
||||||
/* List this explicitly as otherwise .note.gnu.build-id will be
|
ASSERT(. <= IMAGE_ENTRY, "stage3b size must be smaller than 0x10000 bytes")
|
||||||
* put at 0x0 */
|
|
||||||
.notes : {
|
|
||||||
*(.note.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sections to be discarded */
|
/* Sections to be discarded */
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
*(.interp)
|
||||||
|
*(.note.GNU-stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
.org 0x0
|
.org 0x0
|
||||||
.section .text.start
|
.section .text.start
|
||||||
.globl stage3b_reloc_start
|
.globl _start
|
||||||
stage3b_reloc_start:
|
_start:
|
||||||
/* Might be called after a diag308 so better set
|
/* Might be called after a diag308 so better set
|
||||||
* architecture and addressing mode
|
* architecture and addressing mode
|
||||||
*/
|
*/
|
||||||
@@ -53,3 +53,8 @@ stage3b_start:
|
|||||||
.incbin "stage3b.bin"
|
.incbin "stage3b.bin"
|
||||||
stage3b_end:
|
stage3b_end:
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
/* The code doesn't require an executable stack */
|
||||||
|
#if defined(__linux__) && defined(__ELF__)
|
||||||
|
.section .note.GNU-stack,"",%progbits
|
||||||
|
#endif
|
||||||
|
|||||||
19
genprotimg/boot/stage3b_reloc.lds.S
Normal file
19
genprotimg/boot/stage3b_reloc.lds.S
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||||
|
OUTPUT_ARCH(s390:64-bit)
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : {
|
||||||
|
*(.text.start)
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections to be discarded */
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame)
|
||||||
|
*(.interp)
|
||||||
|
*(.note.GNU-stack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,8 @@ host.
|
|||||||
Specifies the certificate that is used to establish a chain of trust
|
Specifies the certificate that is used to establish a chain of trust
|
||||||
for the verification of the host-key documents. Specify this option
|
for the verification of the host-key documents. Specify this option
|
||||||
twice to specify the IBM Z signing key and the intermediate CA
|
twice to specify the IBM Z signing key and the intermediate CA
|
||||||
certificate (signed by the root CA). Required.
|
certificate (signed by the root CA).
|
||||||
|
Required. Ignored if \fB--no-verify\fP is specified.
|
||||||
.TP
|
.TP
|
||||||
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
|
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
|
||||||
Specifies the output file. Required.
|
Specifies the output file. Required.
|
||||||
@@ -91,8 +92,9 @@ the system wide root CAs installed on the system is used. Use
|
|||||||
this only if you trust the specified certificate. Optional.
|
this only if you trust the specified certificate. Optional.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-no-verify\fR
|
\fB\-\-no-verify\fR
|
||||||
Do not require the host-key documents to be valid. For testing
|
Does not require the host-key documents to be valid.
|
||||||
purposes, do not use for a production image. Optional.
|
Do not use for a production image unless you verified
|
||||||
|
the host-key document before. Optional.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-comm\-key\fR=\fI\,FILE\/\fR
|
\fB\-\-comm\-key\fR=\fI\,FILE\/\fR
|
||||||
Specifies the encryption key you want to use for the PV guest dump. Use a
|
Specifies the encryption key you want to use for the PV guest dump. Use a
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
|||||||
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
|
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
|
||||||
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
||||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||||
-Wpointer-arith -Werror -Wno-error=inline \
|
-Wpointer-arith -Wno-error=inline \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
||||||
@@ -36,21 +36,12 @@ ALL_CPPFLAGS += $(INCLUDE_PARMS)
|
|||||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
LIBCURL_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
LIBCURL_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
|
||||||
else
|
|
||||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
|
||||||
GLIB2_LIBS := -lglib-2.0
|
|
||||||
LIBCRYPTO_CFLAGS :=
|
|
||||||
LIBCRYPTO_LIBS := -lcrypto
|
|
||||||
LIBCURL_CFLAGS :=
|
|
||||||
LIBCURL_LIBS := -lcurl
|
|
||||||
endif
|
|
||||||
|
|
||||||
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
||||||
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
|
|
||||||
#define GETTEXT_PACKAGE "genprotimg"
|
#define GETTEXT_PACKAGE "genprotimg"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "boot/linux_layout.h"
|
#include "boot/linux_layout.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
static const gchar tool_name[] = "genprotimg";
|
static const gchar tool_name[] = "genprotimg";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
|
|
||||||
|
|||||||
@@ -280,7 +280,8 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
|||||||
.arg_data = &args->host_keys,
|
.arg_data = &args->host_keys,
|
||||||
.description =
|
.description =
|
||||||
_("FILE specifies a host-key document. At least\n" INDENT
|
_("FILE specifies a host-key document. At least\n" INDENT
|
||||||
"one is required."),
|
"one is required Specify this option multiple times\n" INDENT
|
||||||
|
"to enable the image to run on more than one host."),
|
||||||
.arg_description = _("FILE") },
|
.arg_description = _("FILE") },
|
||||||
{ .long_name = "cert",
|
{ .long_name = "cert",
|
||||||
.short_name = 'C',
|
.short_name = 'C',
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "utils/align.h"
|
#include "utils/align.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "utils/align.h"
|
#include "utils/align.h"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "include/pv_hdr_def.h"
|
#include "include/pv_hdr_def.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3a.h"
|
#include "boot/stage3a.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
#include "pv_args.h"
|
#include "pv_args.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_hdr_def.h"
|
#include "include/pv_hdr_def.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
#ifndef PV_UTILS_ALIGN_H
|
#ifndef PV_UTILS_ALIGN_H
|
||||||
#define PV_UTILS_ALIGN_H
|
#define PV_UTILS_ALIGN_H
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
#include "boot/page.h"
|
||||||
|
|
||||||
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
|
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/page.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
#include "pv/pv_error.h"
|
#include "pv/pv_error.h"
|
||||||
@@ -447,7 +447,7 @@ static X509_CRL *load_crl_from_bio(BIO *bio)
|
|||||||
return g_steal_pointer(&crl);
|
return g_steal_pointer(&crl);
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
rc = BIO_reset(bio);
|
rc = BIO_reset(bio);
|
||||||
if (rc != 1 || (rc != 0 && BIO_method_type(bio) == BIO_TYPE_FILE))
|
if (rc != 1 && !(rc == 0 && BIO_method_type(bio) == BIO_TYPE_FILE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* maybe the CRL is stored in DER format */
|
/* maybe the CRL is stored in DER format */
|
||||||
@@ -533,7 +533,7 @@ X509 *load_cert_from_file(const char *path, GError **err)
|
|||||||
return g_steal_pointer(&cert);
|
return g_steal_pointer(&cert);
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
rc = BIO_reset(bio);
|
rc = BIO_reset(bio);
|
||||||
if (rc != 1 || (rc != 0 && BIO_method_type(bio) == BIO_TYPE_FILE)) {
|
if (rc != 1 && !(rc == 0 && BIO_method_type(bio) == BIO_TYPE_FILE)) {
|
||||||
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE,
|
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE,
|
||||||
_("unable to load certificate: '%s'"), path);
|
_("unable to load certificate: '%s'"), path);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -19,13 +19,8 @@ check_dep:
|
|||||||
"fuse3-devel or libfuse3-dev", \
|
"fuse3-devel or libfuse3-dev", \
|
||||||
"HAVE_FUSE=0")
|
"HAVE_FUSE=0")
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
|
||||||
else
|
|
||||||
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
|
||||||
FUSE_LDLIBS = -lfuse3
|
|
||||||
endif
|
|
||||||
ALL_CFLAGS += -DFUSE_USE_VERSION=30 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
|
ALL_CFLAGS += -DFUSE_USE_VERSION=30 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
|
||||||
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
|
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
|
||||||
|
|
||||||
@@ -52,7 +47,7 @@ install-scripts: lshmc
|
|||||||
cat $$i | \
|
cat $$i | \
|
||||||
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
>$(DESTDIR)$(USRSBINDIR)/$$i; \
|
>$(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||||
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
|
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
@@ -22,26 +22,16 @@ else # HAVE_FUSE
|
|||||||
#
|
#
|
||||||
# FUSE
|
# FUSE
|
||||||
#
|
#
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
|
||||||
else
|
|
||||||
FUSE_CFLAGS = -I/usr/include/fuse3
|
|
||||||
FUSE_LDLIBS = -lfuse3
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# systemd
|
# systemd
|
||||||
#
|
#
|
||||||
ifneq (${HAVE_SYSTEMD},0)
|
ifneq (${HAVE_SYSTEMD},0)
|
||||||
ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
|
ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
SYSTEMD_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd)
|
||||||
SYSTEMD_CFLAGS = $(shell pkg-config --silence-errors --cflags libsystemd)
|
SYSTEMD_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd)
|
||||||
SYSTEMD_LDLIBS = $(shell pkg-config --silence-errors --libs libsystemd)
|
|
||||||
else
|
|
||||||
SYSTEMD_CFLAGS =
|
|
||||||
SYSTEMD_LDLIBS = -lsystemd
|
|
||||||
endif
|
|
||||||
ALL_CPPFLAGS += -DHAVE_SYSTEMD
|
ALL_CPPFLAGS += -DHAVE_SYSTEMD
|
||||||
else
|
else
|
||||||
$(warning "systemd support disabled")
|
$(warning "systemd support disabled")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ all:
|
|||||||
install: hsci
|
install: hsci
|
||||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
|
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
|
||||||
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
|
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ static struct sd_sys_item *l_sys_item_vec[] = {
|
|||||||
static struct sd_sys_item *l_sys_item_enable_vec[] = {
|
static struct sd_sys_item *l_sys_item_enable_vec[] = {
|
||||||
&sd_sys_item_core_cnt,
|
&sd_sys_item_core_cnt,
|
||||||
&sd_sys_item_core_diff,
|
&sd_sys_item_core_diff,
|
||||||
|
&sd_sys_item_thread_diff,
|
||||||
&sd_sys_item_mgm_diff,
|
&sd_sys_item_mgm_diff,
|
||||||
&sd_sys_item_core,
|
&sd_sys_item_core,
|
||||||
&sd_sys_item_mgm,
|
&sd_sys_item_mgm,
|
||||||
@@ -339,6 +340,7 @@ static struct sd_cpu_item *l_cpu_item_vec[] = {
|
|||||||
static struct sd_cpu_item *l_cpu_item_enable_vec[] = {
|
static struct sd_cpu_item *l_cpu_item_enable_vec[] = {
|
||||||
&sd_cpu_item_type,
|
&sd_cpu_item_type,
|
||||||
&sd_cpu_item_core_diff,
|
&sd_cpu_item_core_diff,
|
||||||
|
&sd_cpu_item_thread_diff,
|
||||||
&sd_cpu_item_mgm_diff,
|
&sd_cpu_item_mgm_diff,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,11 +57,42 @@ struct linear_blockptr {
|
|||||||
uint8_t reserved[4];
|
uint8_t reserved[4];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format of a boot record on ECKD DASD for List-Directed IPL
|
||||||
|
*/
|
||||||
|
struct eckd_boot_record {
|
||||||
|
uint8_t magic[4];
|
||||||
|
uint32_t version_id;
|
||||||
|
uint8_t unused[8];
|
||||||
|
uint8_t program_table_pointer[16];
|
||||||
|
uint8_t reserved[478];
|
||||||
|
uint16_t os_id;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Layout of block pointer for cylinder/head/sector devices
|
* Layout of block pointer for cylinder/head/sector devices
|
||||||
* e.g. ECKD
|
* e.g. ECKD
|
||||||
*/
|
*/
|
||||||
struct eckd_blockptr {
|
|
||||||
|
enum blkptr_format_id {
|
||||||
|
/*
|
||||||
|
* this is the old format which serves only CCW-type IPL,
|
||||||
|
* and doesn't fit List-Directed IPL. Still supported for
|
||||||
|
* compatibility reasons.
|
||||||
|
*/
|
||||||
|
LEGACY_BLKPTR_FORMAT_ID,
|
||||||
|
/*
|
||||||
|
* this is the "new" format which serves only List-Directed IPL,
|
||||||
|
* but is also suitable for CCW-type IPL.
|
||||||
|
*/
|
||||||
|
BLKPTR_FORMAT_ID,
|
||||||
|
NR_BLKPTR_FORMATS
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block pointers format identified as LEGACY_BLKPTR_FORMAT_ID.
|
||||||
|
*/
|
||||||
|
struct eckd_blockptr_legacy {
|
||||||
uint16_t cyl;
|
uint16_t cyl;
|
||||||
uint16_t head;
|
uint16_t head;
|
||||||
uint8_t sec;
|
uint8_t sec;
|
||||||
@@ -70,10 +101,22 @@ struct eckd_blockptr {
|
|||||||
uint8_t reserved[8];
|
uint8_t reserved[8];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block pointers format identified as BLKPTR_FORMAT_ID.
|
||||||
|
*/
|
||||||
|
struct eckd_blockptr {
|
||||||
|
uint32_t cyl;
|
||||||
|
uint8_t head;
|
||||||
|
uint8_t sec;
|
||||||
|
uint8_t reserved1[4];
|
||||||
|
uint16_t blockct;
|
||||||
|
uint8_t reserved2[4];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
COMPONENT_EXECUTE = 0x01,
|
COMPONENT_TYPE_EXECUTE = 0x01,
|
||||||
COMPONENT_LOAD = 0x02,
|
COMPONENT_TYPE_LOAD = 0x02,
|
||||||
COMPONENT_SIGNATURE = 0x03
|
COMPONENT_TYPE_SIGNATURE = 0x03
|
||||||
} component_type;
|
} component_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -117,7 +160,8 @@ struct scsi_dump_sb {
|
|||||||
uint64_t csum_offset;
|
uint64_t csum_offset;
|
||||||
uint64_t csum_size;
|
uint64_t csum_size;
|
||||||
uint64_t csum;
|
uint64_t csum;
|
||||||
} __packed;
|
};
|
||||||
|
STATIC_ASSERT(sizeof(struct scsi_dump_sb) == 72);
|
||||||
|
|
||||||
#define SCSI_DUMP_SB_MAGIC 0x5a46435044554d50ULL /* ZFCPDUMP */
|
#define SCSI_DUMP_SB_MAGIC 0x5a46435044554d50ULL /* ZFCPDUMP */
|
||||||
/* To avoid a csum entry of 0 a seed is used */
|
/* To avoid a csum entry of 0 a seed is used */
|
||||||
@@ -151,14 +195,25 @@ struct boot_info_bp_dump {
|
|||||||
uint8_t unused[16];
|
uint8_t unused[16];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* This represents on-disk pointer to a block on disk */
|
||||||
|
union disk_blockptr {
|
||||||
|
struct eckd_blockptr_legacy eckd_legacy;
|
||||||
|
struct eckd_blockptr eckd;
|
||||||
|
struct linear_blockptr linear;
|
||||||
|
};
|
||||||
|
|
||||||
struct boot_info_bp_ipl {
|
struct boot_info_bp_ipl {
|
||||||
union {
|
union disk_blockptr bm_ptr;
|
||||||
struct eckd_blockptr eckd;
|
|
||||||
struct linear_blockptr lin;
|
|
||||||
} bm_ptr;
|
|
||||||
uint8_t unused[16];
|
uint8_t unused[16];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct disk_program_table {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
uint64_t unused;
|
||||||
|
union disk_blockptr component_table[0];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct boot_info {
|
struct boot_info {
|
||||||
char magic[4];
|
char magic[4];
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#define IPL_H
|
#define IPL_H
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "s390.h"
|
#include "page.h"
|
||||||
|
|
||||||
#define IPL_FLAG_SECURE 0x40
|
#define IPL_FLAG_SECURE 0x40
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,18 @@
|
|||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "linux_layout.h"
|
#include "linux_layout.h"
|
||||||
|
|
||||||
|
#define STAGE0_LOAD_ADDRESS _AC(0x0, UL)
|
||||||
|
|
||||||
|
#define STAGE1_LOAD_ADDRESS _AC(0x18, UL)
|
||||||
|
#define STAGE1B_LOAD_ADDRESS _AC(0xe000, UL)
|
||||||
|
|
||||||
#define STAGE2_DESC _AC(0x78, UL)
|
#define STAGE2_DESC _AC(0x78, UL)
|
||||||
#define STAGE2_ENTRY _AC(0x2018, UL)
|
#define STAGE2_ENTRY _AC(0x2018, UL)
|
||||||
#define STAGE2_HEAP_ADDRESS _AC(0x6000, UL)
|
#define STAGE2_HEAP_ADDRESS _AC(0x6000, UL)
|
||||||
#define STAGE2_HEAP_SIZE _AC(0x3000, UL)
|
#define STAGE2_HEAP_SIZE _AC(0x3000, UL)
|
||||||
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
||||||
#define STAGE2_STACK_SIZE _AC(0x1c00, UL)
|
#define STAGE2_STACK_SIZE _AC(0x1c00, UL)
|
||||||
|
#define STAGE2_MAX_SIZE _AC(0x3000, UL)
|
||||||
|
|
||||||
#define STAGE3_ENTRY _AC(0xa000, UL)
|
#define STAGE3_ENTRY _AC(0xa000, UL)
|
||||||
|
|
||||||
|
|||||||
15
include/boot/page.h
Normal file
15
include/boot/page.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Page related definitions and functions.
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2023
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOT_PAGE_H
|
||||||
|
#define BOOT_PAGE_H
|
||||||
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
|
#define PAGE_SIZE _AC(4096, UL)
|
||||||
|
#endif
|
||||||
31
include/boot/psw.h
Normal file
31
include/boot/psw.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Program Status Word related definitions and functions.
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2023
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOT_PSW_H
|
||||||
|
#define BOOT_PSW_H
|
||||||
|
|
||||||
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
|
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
||||||
|
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
||||||
|
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
||||||
|
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
||||||
|
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
||||||
|
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct psw_t {
|
||||||
|
uint64_t mask;
|
||||||
|
uint64_t addr;
|
||||||
|
} __aligned(8);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* s390 related definitions and functions.
|
* s390 related definitions and functions.
|
||||||
|
* Should only be used for code targeting s390 (bootloader code)
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2013, 2020
|
* Copyright IBM Corp. 2013, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,29 +13,22 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/sigp.h"
|
#include "boot/sigp.h"
|
||||||
|
#include "boot/psw.h"
|
||||||
|
#include "boot/page.h"
|
||||||
|
|
||||||
#define __LC_IPLDEV 0x0c6c
|
#define __LC_IPLDEV 0x0c6c
|
||||||
#define __LC_OS_INFO 0x0e18
|
#define __LC_OS_INFO 0x0e18
|
||||||
|
|
||||||
#define LOWCORE_SIZE _AC(0x2000, UL)
|
#define LOWCORE_SIZE _AC(0x2000, UL)
|
||||||
|
|
||||||
#define PAGE_SIZE _AC(4096, UL)
|
|
||||||
|
|
||||||
/* Minimum size of a stack frame in bytes */
|
/* Minimum size of a stack frame in bytes */
|
||||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||||
|
|
||||||
/* Facilities */
|
/* Facilities */
|
||||||
#define UNPACK_FACILITY _AC(161, U)
|
#define UNPACK_FACILITY _AC(161, U)
|
||||||
|
|
||||||
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
|
||||||
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
|
||||||
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
|
||||||
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
|
||||||
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
|
||||||
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper macro for exception table entries
|
* Helper macro for exception table entries
|
||||||
@@ -46,18 +40,6 @@
|
|||||||
".long (" #_target ")\n" \
|
".long (" #_target ")\n" \
|
||||||
".previous\n"
|
".previous\n"
|
||||||
|
|
||||||
struct psw_t {
|
|
||||||
uint64_t mask;
|
|
||||||
uint64_t addr;
|
|
||||||
} __aligned(8);
|
|
||||||
|
|
||||||
struct psw32_t {
|
|
||||||
uint32_t mask;
|
|
||||||
uint32_t addr;
|
|
||||||
} __aligned(8);
|
|
||||||
|
|
||||||
void load_wait_psw(uint64_t, struct psw_t *);
|
|
||||||
|
|
||||||
struct subchannel_id {
|
struct subchannel_id {
|
||||||
uint32_t cssid:8;
|
uint32_t cssid:8;
|
||||||
uint32_t:4;
|
uint32_t:4;
|
||||||
|
|||||||
@@ -90,5 +90,6 @@ void ap_list_remove_all(struct util_list *list);
|
|||||||
int ap_get_lock(void);
|
int ap_get_lock(void);
|
||||||
int ap_get_lock_callout(void);
|
int ap_get_lock_callout(void);
|
||||||
int ap_release_lock(void);
|
int ap_release_lock(void);
|
||||||
|
int ap_release_lock_callout(void);
|
||||||
|
|
||||||
#endif /* LIB_AP_H */
|
#endif /* LIB_AP_H */
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
/* A bus id of a DASD is 8 characters long. E.g. 0.0.4711 */
|
/* the definition of a BUSID in the DASD driver is 20 */
|
||||||
#define DASD_BUS_ID_SIZE 9
|
#define DASD_BUS_ID_SIZE 20
|
||||||
|
|
||||||
typedef struct dasd_information2_t {
|
typedef struct dasd_information2_t {
|
||||||
unsigned int devno; /* S/390 devno */
|
unsigned int devno; /* S/390 devno */
|
||||||
@@ -187,6 +187,68 @@ typedef struct format_check_t {
|
|||||||
#define DASD_FMT_ERR_RECORD_ID 4
|
#define DASD_FMT_ERR_RECORD_ID 4
|
||||||
#define DASD_FMT_ERR_KEY_LENGTH 5
|
#define DASD_FMT_ERR_KEY_LENGTH 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct profile_info_t
|
||||||
|
* holds the profiling information
|
||||||
|
*/
|
||||||
|
typedef struct dasd_profile_info_t {
|
||||||
|
unsigned int dasd_io_reqs; /* # of requests processed at all */
|
||||||
|
unsigned int dasd_io_sects; /* # of sectors processed at all */
|
||||||
|
unsigned int dasd_io_secs[32]; /* request's sizes */
|
||||||
|
unsigned int dasd_io_times[32]; /* requests's times */
|
||||||
|
unsigned int dasd_io_timps[32]; /* requests's times per sector */
|
||||||
|
unsigned int dasd_io_time1[32]; /* time from build to start */
|
||||||
|
unsigned int dasd_io_time2[32]; /* time from start to irq */
|
||||||
|
unsigned int dasd_io_time2ps[32]; /* time from start to irq */
|
||||||
|
unsigned int dasd_io_time3[32]; /* time from irq to end */
|
||||||
|
unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */
|
||||||
|
} dasd_profile_info_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct attrib_data_t
|
||||||
|
* represents the operation (cache) bits for the device.
|
||||||
|
* Used in DE to influence caching of the DASD.
|
||||||
|
*/
|
||||||
|
typedef struct attrib_data_t {
|
||||||
|
unsigned char operation : 3; /* cache operation mode */
|
||||||
|
unsigned char reserved : 5;
|
||||||
|
unsigned short nr_cyl; /* no of cyliners for read ahaed */
|
||||||
|
unsigned char reserved2[29]; /* for future use */
|
||||||
|
} __attribute__((packed)) attrib_data_t;
|
||||||
|
|
||||||
|
/* definition of operation (cache) bits within attributes of DE */
|
||||||
|
#define DASD_NORMAL_CACHE 0x0
|
||||||
|
#define DASD_BYPASS_CACHE 0x1
|
||||||
|
#define DASD_INHIBIT_LOAD 0x2
|
||||||
|
#define DASD_SEQ_ACCESS 0x3
|
||||||
|
#define DASD_SEQ_PRESTAGE 0x4
|
||||||
|
#define DASD_REC_ACCESS 0x5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data returned by Sense Path Group ID (SNID)
|
||||||
|
*/
|
||||||
|
struct dasd_snid_data {
|
||||||
|
struct {
|
||||||
|
__u8 group : 2;
|
||||||
|
__u8 reserve : 2;
|
||||||
|
__u8 mode : 1;
|
||||||
|
__u8 res : 3;
|
||||||
|
} __attribute__((packed)) path_state;
|
||||||
|
__u8 pgid[11];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct dasd_snid_ioctl_data {
|
||||||
|
struct dasd_snid_data data;
|
||||||
|
__u8 path_mask;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct dasd_copypair_swap_data {
|
||||||
|
char primary[DASD_BUS_ID_SIZE]; /* BUSID of primary */
|
||||||
|
char secondary[DASD_BUS_ID_SIZE]; /* BUSID of secondary */
|
||||||
|
/* Reserved for future updates. */
|
||||||
|
char reserved[64];
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
/* definition from hdreg.h */
|
/* definition from hdreg.h */
|
||||||
struct hd_geometry {
|
struct hd_geometry {
|
||||||
@@ -207,27 +269,29 @@ struct hd_geometry {
|
|||||||
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
||||||
/* Release the device for the current LPAR */
|
/* Release the device for the current LPAR */
|
||||||
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
||||||
|
/* Unconditional reserve the device for the current LPAR */
|
||||||
|
#define BIODASDSLCK _IO(DASD_IOCTL_LETTER, 4)
|
||||||
|
/* reset profiling information of a device */
|
||||||
|
#define BIODASDPRRST _IO(DASD_IOCTL_LETTER, 5)
|
||||||
|
/* retrieve profiling information of a device */
|
||||||
|
#define BIODASDPRRD _IOR(DASD_IOCTL_LETTER, 2, dasd_profile_info_t)
|
||||||
/* Get information on a dasd device (enhanced) */
|
/* Get information on a dasd device (enhanced) */
|
||||||
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
||||||
|
/* Get Attributes (cache operations) */
|
||||||
|
#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER, 5, attrib_data_t)
|
||||||
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
||||||
#define BIODASDFMT _IOW(DASD_IOCTL_LETTER, 1, format_data_t)
|
#define BIODASDFMT _IOW(DASD_IOCTL_LETTER, 1, format_data_t)
|
||||||
|
/* Set Attributes (cache operations) */
|
||||||
|
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER, 2, attrib_data_t)
|
||||||
/* Release Allocated Space */
|
/* Release Allocated Space */
|
||||||
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
|
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
|
||||||
|
/* Swap copy pair */
|
||||||
|
#define BIODASDPPRCSWAP _IOW(DASD_IOCTL_LETTER, 4, struct dasd_copypair_swap_data)
|
||||||
|
/* Get Sense Path Group ID (SNID) data */
|
||||||
|
#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
|
||||||
/* Check device format according to format_data_t */
|
/* Check device format according to format_data_t */
|
||||||
#define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t)
|
#define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t)
|
||||||
|
|
||||||
/********************************************************************************
|
|
||||||
* SECTION: Further IOCTL Definitions (see fs.h and hdreq.h)
|
|
||||||
*******************************************************************************/
|
|
||||||
/* get read-only status (0 = read_write) */
|
|
||||||
#define BLKROGET _IO(0x12, 94)
|
|
||||||
/* re-read partition table */
|
|
||||||
#define BLKRRPART _IO(0x12, 95)
|
|
||||||
/* get block device sector size */
|
|
||||||
#define BLKSSZGET _IO(0x12, 104)
|
|
||||||
/* return device size in bytes (u64 *arg) */
|
|
||||||
#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
|
|
||||||
|
|
||||||
#ifndef __linux__ /* from <linux/hdreg.h> */
|
#ifndef __linux__ /* from <linux/hdreg.h> */
|
||||||
#define HDIO_GETGEO 0x0301
|
#define HDIO_GETGEO 0x0301
|
||||||
#endif
|
#endif
|
||||||
@@ -245,5 +309,12 @@ int dasd_is_ro(const char *device, bool *ro);
|
|||||||
int dasd_reread_partition_table(const char *device, int ntries);
|
int dasd_reread_partition_table(const char *device, int ntries);
|
||||||
int dasd_disk_reserve(const char *device);
|
int dasd_disk_reserve(const char *device);
|
||||||
int dasd_disk_release(const char *device);
|
int dasd_disk_release(const char *device);
|
||||||
|
int dasd_slock(const char *device);
|
||||||
|
int dasd_get_cache(const char *device, attrib_data_t *attrib_data);
|
||||||
|
int dasd_set_cache(const char *device, attrib_data_t *attrib_data);
|
||||||
|
int dasd_query_reserve(const char *device);
|
||||||
|
int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info);
|
||||||
|
int dasd_reset_profile(const char *device);
|
||||||
|
int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data);
|
||||||
|
|
||||||
#endif /* LIB_DASD_BASE_H */
|
#endif /* LIB_DASD_BASE_H */
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
#define S390_CPUS_ONLINE "/sys/devices/system/cpu/online"
|
#define S390_CPUS_ONLINE "/sys/devices/system/cpu/online"
|
||||||
#define S390_CPUMSF_BUFFERSZ "/sys/module/kernel/parameters/cpum_sfb_size"
|
#define S390_CPUMSF_BUFFERSZ "/sys/module/kernel/parameters/cpum_sfb_size"
|
||||||
#define S390_SYSFS_PAI_CRYPTO "/sys/devices/pai_crypto/"
|
#define S390_SYSFS_PAI_CRYPTO "/sys/devices/pai_crypto/"
|
||||||
#define S390_SYSFS_PAI_NNPA "/sys/devices/pai_nnpa/"
|
#define S390_SYSFS_PAI_EXT "/sys/devices/pai_ext/"
|
||||||
|
#define S390_SYSFS_PAI_NNPA S390_SYSFS_PAI_EXT "events/NNPA_ALL"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read out the PMU type from a given file.
|
* Read out the PMU type from a given file.
|
||||||
@@ -146,6 +147,14 @@ bool libcpumf_sfb_info(unsigned long *min, unsigned long *max);
|
|||||||
*/
|
*/
|
||||||
bool libcpumf_have_pai_crypto(void);
|
bool libcpumf_have_pai_crypto(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if PAI_EXTENSION Facility is supported.
|
||||||
|
*
|
||||||
|
* @retval true PAI_EXTENSION counter Facility is available
|
||||||
|
* @retval false PAI_EXTENSION counter Facility is not available
|
||||||
|
*/
|
||||||
|
bool libcpumf_have_pai_ext(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if PAI_NNPA counter Facility is supported. This PMU facility
|
* Return true if PAI_NNPA counter Facility is supported. This PMU facility
|
||||||
* supports the Neural Network Processing Assist (NNPA) counter set.
|
* supports the Neural Network Processing Assist (NNPA) counter set.
|
||||||
|
|||||||
26
include/lib/util_lockfile.h
Normal file
26
include/lib/util_lockfile.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* @defgroup util_lockfile_h util_lockfile: File locking utility
|
||||||
|
* @{
|
||||||
|
* @brief Create file-based locks
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2022
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
#ifndef LIB_UTIL_LOCKFILE_H
|
||||||
|
#define LIB_UTIL_LOCKFILE_H
|
||||||
|
|
||||||
|
#define UTIL_LOCKFILE_OK 0 /* Lock acquired/released successfully */
|
||||||
|
#define UTIL_LOCKFILE_LOCK_FAIL 1 /* Lock already held, ran out of retries */
|
||||||
|
#define UTIL_LOCKFILE_RELEASE_NONE 2 /* Lock not held */
|
||||||
|
#define UTIL_LOCKFILE_RELEASE_FAIL 3 /* Lock not held by specified pid */
|
||||||
|
#define UTIL_LOCKFILE_ERR 4 /* Other, unexpected error conditions */
|
||||||
|
|
||||||
|
int util_lockfile_lock(char *lockfile, int retries);
|
||||||
|
int util_lockfile_parent_lock(char *lockfile, int retries);
|
||||||
|
|
||||||
|
int util_lockfile_release(char *lockfile);
|
||||||
|
int util_lockfile_parent_release(char *lockfile);
|
||||||
|
|
||||||
|
#endif /** LIB_UTIL_LOCKFILE_H @} */
|
||||||
@@ -97,6 +97,24 @@ typedef struct volume_label
|
|||||||
unsigned long long formatted_blocks; /* valid when ldl_version >= f2 */
|
unsigned long long formatted_blocks; /* valid when ldl_version >= f2 */
|
||||||
} __attribute__ ((packed)) volume_label_t;
|
} __attribute__ ((packed)) volume_label_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents a volume label specific for OS/390 compatible disk layout
|
||||||
|
*/
|
||||||
|
struct vol_label_cdl {
|
||||||
|
char volkey[4];
|
||||||
|
char vollbl[4];
|
||||||
|
char opaq[70];
|
||||||
|
cchhb_t br; /* boot record address */
|
||||||
|
char stdv[1]; /* standard version ID */
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
static inline int is_vol1(char *this)
|
||||||
|
{
|
||||||
|
char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00} /* "VOL1" in EBCDIC */;
|
||||||
|
|
||||||
|
return !strncmp(this, vol1, 4);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct extent
|
typedef struct extent
|
||||||
{
|
{
|
||||||
u_int8_t typeind; /* extent type indicator */
|
u_int8_t typeind; /* extent type indicator */
|
||||||
|
|||||||
@@ -21,15 +21,21 @@
|
|||||||
* Usage example:
|
* Usage example:
|
||||||
* #define IMAGE_ENTRY _AC(0x10000, UL)
|
* #define IMAGE_ENTRY _AC(0x10000, UL)
|
||||||
*/
|
*/
|
||||||
|
#ifndef _AC
|
||||||
#ifdef __ASSEMBLER__
|
#ifdef __ASSEMBLER__
|
||||||
#define _AC(X, TYPE) X
|
#define _AC(X, TYPE) X
|
||||||
#else
|
#else
|
||||||
#define _AC(X, TYPE) X##TYPE
|
#define _AC(X, TYPE) X##TYPE
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#ifndef sizeof_field
|
||||||
|
#define sizeof_field(type, field) (sizeof((type *)0)->field)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef UNUSED
|
#ifdef UNUSED
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
||||||
@@ -48,6 +54,10 @@
|
|||||||
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
#ifndef ROUNDUP
|
||||||
|
# define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE)
|
#define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE)
|
||||||
#define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR)
|
#define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR)
|
||||||
#define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR)
|
#define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR)
|
||||||
@@ -60,6 +70,7 @@
|
|||||||
#define __may_alias __attribute__((may_alias))
|
#define __may_alias __attribute__((may_alias))
|
||||||
#define __section(x) __attribute__((__section__(#x)))
|
#define __section(x) __attribute__((__section__(#x)))
|
||||||
#define __noinline __attribute__((__noinline__))
|
#define __noinline __attribute__((__noinline__))
|
||||||
|
#define __big_endian
|
||||||
/* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define
|
/* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define
|
||||||
* __always_inline. Therefore undefine it first to allow the headers
|
* __always_inline. Therefore undefine it first to allow the headers
|
||||||
* to be included first.
|
* to be included first.
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ typedef enum {
|
|||||||
PV_CERT_ERROR_MALFORMED_ROOT_CA,
|
PV_CERT_ERROR_MALFORMED_ROOT_CA,
|
||||||
PV_CERT_ERROR_NO_CRL,
|
PV_CERT_ERROR_NO_CRL,
|
||||||
PV_CERT_ERROR_NO_CRLDP,
|
PV_CERT_ERROR_NO_CRLDP,
|
||||||
|
PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
PV_CERT_ERROR_NO_ISSUER_IBM_Z_FOUND,
|
PV_CERT_ERROR_NO_ISSUER_IBM_Z_FOUND,
|
||||||
PV_CERT_ERROR_NO_PUBLIC_KEY,
|
PV_CERT_ERROR_NO_PUBLIC_KEY,
|
||||||
PV_CERT_ERROR_READ_CERTIFICATE,
|
PV_CERT_ERROR_READ_CERTIFICATE,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "libpv/glib-helper.h"
|
#include "libpv/glib-helper.h"
|
||||||
|
|
||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "libpv/openssl-compat.h"
|
#include "libpv/openssl-compat.h"
|
||||||
#include "libpv/macros.h"
|
#include "libpv/macros.h"
|
||||||
|
|||||||
@@ -42,11 +42,14 @@ enum PvCryptoMode {
|
|||||||
PV_DECRYPT,
|
PV_DECRYPT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** pv_get_openssl_error:
|
/** pv_get_openssl_errors:
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): String representing the error.
|
* Returns the last OpenSSL error messages.
|
||||||
|
* Caller is responsible to free the returned value.
|
||||||
|
*
|
||||||
|
* Returns: String representing the error.
|
||||||
*/
|
*/
|
||||||
const char *pv_get_openssl_error(void);
|
char *pv_get_openssl_errors(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_BIO_reset:
|
* pv_BIO_reset:
|
||||||
@@ -181,7 +184,6 @@ typedef enum {
|
|||||||
PV_CRYPTO_ERROR_KEYGENERATION,
|
PV_CRYPTO_ERROR_KEYGENERATION,
|
||||||
PV_CRYPTO_ERROR_RANDOMIZATION,
|
PV_CRYPTO_ERROR_RANDOMIZATION,
|
||||||
PV_CRYPTO_ERROR_READ_FILE,
|
PV_CRYPTO_ERROR_READ_FILE,
|
||||||
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
|
||||||
PV_CRYPTO_ERROR_NO_MATCH_TAG,
|
PV_CRYPTO_ERROR_NO_MATCH_TAG,
|
||||||
} PvCryptoErrors;
|
} PvCryptoErrors;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,12 @@
|
|||||||
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
|
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56
|
||||||
|
|
||||||
|
#ifdef __G_LIB_H__
|
||||||
|
#error "glib.h must be included via libpv/glib-helper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -102,9 +108,12 @@ FILE *pv_file_open(const char *filename, const char *mode, GError **error);
|
|||||||
|
|
||||||
/** pv_gbytes_memcpy:
|
/** pv_gbytes_memcpy:
|
||||||
*
|
*
|
||||||
* memcpy with size check.
|
* memcpy with size check. In case @dst_size is smaller than the size of @src
|
||||||
|
* the error value %NULL is returned and @copied and @dst are left unchanged.
|
||||||
|
*
|
||||||
|
* If @dst and @src data overlap, the behavior is undefined.
|
||||||
*/
|
*/
|
||||||
void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src);
|
void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied);
|
||||||
|
|
||||||
#define PV_GLIB_HELPER_ERROR g_quark_from_static_string("pv-glib-helper_error-quark")
|
#define PV_GLIB_HELPER_ERROR g_quark_from_static_string("pv-glib-helper_error-quark")
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -10,7 +10,12 @@
|
|||||||
#ifndef LIBPV_MACROS_H
|
#ifndef LIBPV_MACROS_H
|
||||||
#define LIBPV_MACROS_H
|
#define LIBPV_MACROS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PV_NONNULL(...)
|
#define PV_NONNULL(...)
|
||||||
#define DO_PRAGMA(x) _Pragma(#x)
|
#define DO_PRAGMA(x) _Pragma(#x)
|
||||||
|
|
||||||
|
/* Most significant bit */
|
||||||
|
#define PV_MSB(idx) ((uint64_t)1 << (63 - (idx)))
|
||||||
|
|
||||||
#endif /* LIBPV_MACROS_H */
|
#endif /* LIBPV_MACROS_H */
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "libpv/crypto.h"
|
#include "libpv/crypto.h"
|
||||||
|
#include "libpv/macros.h"
|
||||||
|
|
||||||
/* Magic number which is used to identify the file containing the PV
|
/* Magic number which is used to identify the file containing the PV
|
||||||
* header
|
* header
|
||||||
@@ -22,20 +23,17 @@
|
|||||||
#define PV_MAGIC_NUMBER 0x49424d5365634578ULL
|
#define PV_MAGIC_NUMBER 0x49424d5365634578ULL
|
||||||
#define PV_VERSION_1 0x00000100U
|
#define PV_VERSION_1 0x00000100U
|
||||||
|
|
||||||
/* Internal helper macro */
|
|
||||||
#define __PV_BIT(nr) (1ULL << (63 - (nr)))
|
|
||||||
|
|
||||||
/* Plaintext control flags */
|
/* Plaintext control flags */
|
||||||
/* dumping of the configuration is allowed */
|
/* dumping of the configuration is allowed */
|
||||||
#define PV_PCF_ALLOW_DUMPING __PV_BIT(34)
|
#define PV_PCF_ALLOW_DUMPING PV_MSB(34)
|
||||||
/* prevent Ultravisor decryption during unpack operation */
|
/* prevent Ultravisor decryption during unpack operation */
|
||||||
#define PV_PCF_NO_DECRYPTION __PV_BIT(35)
|
#define PV_PCF_NO_DECRYPTION PV_MSB(35)
|
||||||
/* PCKMO encrypt-DEA/TDEA-key functions allowed */
|
/* PCKMO encrypt-DEA/TDEA-key functions allowed */
|
||||||
#define PV_PCF_PCKMO_DEA_TDEA __PV_BIT(56)
|
#define PV_PCF_PCKMO_DEA_TDEA PV_MSB(56)
|
||||||
/* PCKMO encrypt-AES-key functions allowed */
|
/* PCKMO encrypt-AES-key functions allowed */
|
||||||
#define PV_PCF_PCKMO_AES __PV_BIT(57)
|
#define PV_PCF_PCKMO_AES PV_MSB(57)
|
||||||
/* PCKMO encrypt-ECC-key functions allowed */
|
/* PCKMO encrypt-ECC-key functions allowed */
|
||||||
#define PV_PCF_PCKM_ECC __PV_BIT(58)
|
#define PV_PCF_PCKM_ECC PV_MSB(58)
|
||||||
|
|
||||||
/* maxima for the PV version 1 */
|
/* maxima for the PV version 1 */
|
||||||
#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE
|
#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ clean:
|
|||||||
install: ip_watcher.pl xcec-bridge start_hsnc.sh
|
install: ip_watcher.pl xcec-bridge start_hsnc.sh
|
||||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
< start_hsnc.sh >$(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
< start_hsnc.sh >$(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||||
chmod 755 $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
chmod 755 $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ip_watcher.pl \
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ip_watcher.pl \
|
||||||
$(DESTDIR)$(USRSBINDIR)
|
$(DESTDIR)$(USRSBINDIR)
|
||||||
|
|||||||
@@ -23,12 +23,15 @@
|
|||||||
#define BOOTPARMS_CCW_MAX 64
|
#define BOOTPARMS_CCW_MAX 64
|
||||||
#define BOOTPARMS_FCP_MAX 3452
|
#define BOOTPARMS_FCP_MAX 3452
|
||||||
|
|
||||||
|
#define OPT_BRCHR 0x80
|
||||||
|
|
||||||
enum target_type {
|
enum target_type {
|
||||||
TT_CCW,
|
TT_CCW,
|
||||||
TT_FCP,
|
TT_FCP,
|
||||||
TT_NSS,
|
TT_NSS,
|
||||||
TT_NODE,
|
TT_NODE,
|
||||||
TT_NVME,
|
TT_NVME,
|
||||||
|
TT_ECKD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum reipl_type {
|
enum reipl_type {
|
||||||
@@ -36,12 +39,14 @@ enum reipl_type {
|
|||||||
REIPL_CCW,
|
REIPL_CCW,
|
||||||
REIPL_NSS,
|
REIPL_NSS,
|
||||||
REIPL_NVME,
|
REIPL_NVME,
|
||||||
|
REIPL_ECKD,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const usage_chreipl =
|
static const char *const usage_chreipl =
|
||||||
"Usage: %s [TARGET] [ARGS] [OPTIONS]\n"
|
"Usage: %s [TARGET] [ARGS] [OPTIONS]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
|
" chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
|
||||||
|
" chreipl [eckd] [-d] <DEVICE> [OPTIONS]\n"
|
||||||
" chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
|
" chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
|
||||||
" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
|
" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
|
||||||
" chreipl [node] <NODE|DIR> [OPTIONS]\n"
|
" chreipl [node] <NODE|DIR> [OPTIONS]\n"
|
||||||
@@ -50,6 +55,7 @@ static const char *const usage_chreipl =
|
|||||||
"\n"
|
"\n"
|
||||||
"The following re-IPL targets are supported:\n"
|
"The following re-IPL targets are supported:\n"
|
||||||
" ccw IPL from CCW device\n"
|
" ccw IPL from CCW device\n"
|
||||||
|
" eckd IPL from ECKD device\n"
|
||||||
" fcp IPL from FCP device\n"
|
" fcp IPL from FCP device\n"
|
||||||
" nvme IPL from NVME device\n"
|
" nvme IPL from NVME device\n"
|
||||||
" nss IPL from NSS\n"
|
" nss IPL from NSS\n"
|
||||||
@@ -66,6 +72,13 @@ static const char *const usage_chreipl =
|
|||||||
" -L, --loadparm <PARM> Loadparm specification\n"
|
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||||
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"Options for eckd target:\n"
|
||||||
|
" -d, --device <DEVICE> Device number of the ECKD IPL device\n"
|
||||||
|
" -b, --bootprog <BPROG> Bootprog specification\n"
|
||||||
|
" --brchr <C,H,R> Boot record location in Cylinder,Head,Record format\n"
|
||||||
|
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||||
|
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||||
|
"\n"
|
||||||
"Options for fcp target:\n"
|
"Options for fcp target:\n"
|
||||||
" -d, --device <DEVICE> Device number of the adapter of the FCP IPL device\n"
|
" -d, --device <DEVICE> Device number of the adapter of the FCP IPL device\n"
|
||||||
" -l --lun <LUN> Logical unit number of the FCP IPL device\n"
|
" -l --lun <LUN> Logical unit number of the FCP IPL device\n"
|
||||||
@@ -114,6 +127,8 @@ static struct locals {
|
|||||||
int target_type_auto_mode;
|
int target_type_auto_mode;
|
||||||
enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
|
enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
|
||||||
int reipl_clear;
|
int reipl_clear;
|
||||||
|
char *brchr;
|
||||||
|
int brchr_set;
|
||||||
} l;
|
} l;
|
||||||
|
|
||||||
static void __noreturn print_usage_chreipl_exit(void)
|
static void __noreturn print_usage_chreipl_exit(void)
|
||||||
@@ -329,6 +344,19 @@ static void parse_ccw_args(char *nargv[], int nargc)
|
|||||||
set_device(nargv[0]);
|
set_device(nargv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_eckd_args(char *nargv[], int nargc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* we might be called like this:
|
||||||
|
* chreipl eckd 4711
|
||||||
|
*/
|
||||||
|
if (l.busid_set)
|
||||||
|
ERR_EXIT("Use either options or positional parameters");
|
||||||
|
if (nargc > 1)
|
||||||
|
ERR_EXIT("Too many arguments specified for \"eckd\" re-IPL type");
|
||||||
|
set_device(nargv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_nss_args(char *nargv[], int nargc)
|
static void parse_nss_args(char *nargv[], int nargc)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -369,6 +397,8 @@ static int set_reipl_type(const char *dev_name)
|
|||||||
l.reipl_type = REIPL_FCP;
|
l.reipl_type = REIPL_FCP;
|
||||||
else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
|
else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
|
||||||
l.reipl_type = REIPL_NVME;
|
l.reipl_type = REIPL_NVME;
|
||||||
|
else if (strncmp(dev_name, "eckd", strlen("eckd")) == 0)
|
||||||
|
l.reipl_type = REIPL_ECKD;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -493,12 +523,15 @@ static void parse_pos_args(char *nargv[], int nargc)
|
|||||||
case TT_NODE:
|
case TT_NODE:
|
||||||
parse_node_args(nargv, nargc);
|
parse_node_args(nargv, nargc);
|
||||||
break;
|
break;
|
||||||
|
case TT_ECKD:
|
||||||
|
parse_eckd_args(nargv, nargc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_fcp_opts(void)
|
static void check_fcp_opts(void)
|
||||||
{
|
{
|
||||||
if (l.nss_name_set)
|
if (l.nss_name_set || l.brchr_set)
|
||||||
ERR_EXIT("Invalid option for \"fcp\" target specified");
|
ERR_EXIT("Invalid option for \"fcp\" target specified");
|
||||||
if (!(l.busid_set && l.wwpn_set && l.lun_set))
|
if (!(l.busid_set && l.wwpn_set && l.lun_set))
|
||||||
ERR_EXIT("The \"fcp\" target requires device, WWPN, "
|
ERR_EXIT("The \"fcp\" target requires device, WWPN, "
|
||||||
@@ -507,7 +540,8 @@ static void check_fcp_opts(void)
|
|||||||
|
|
||||||
static void check_nvme_opts(void)
|
static void check_nvme_opts(void)
|
||||||
{
|
{
|
||||||
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set)
|
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set ||
|
||||||
|
l.brchr_set)
|
||||||
ERR_EXIT("Invalid option for \"nvme\" target specified");
|
ERR_EXIT("Invalid option for \"nvme\" target specified");
|
||||||
if (!(l.fid_set && l.nsid_set))
|
if (!(l.fid_set && l.nsid_set))
|
||||||
ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
|
ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
|
||||||
@@ -515,16 +549,25 @@ static void check_nvme_opts(void)
|
|||||||
|
|
||||||
static void check_ccw_opts(void)
|
static void check_ccw_opts(void)
|
||||||
{
|
{
|
||||||
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set)
|
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set ||
|
||||||
|
l.brchr_set)
|
||||||
ERR_EXIT("Invalid option for \"ccw\" target specified");
|
ERR_EXIT("Invalid option for \"ccw\" target specified");
|
||||||
if (!l.busid_set)
|
if (!l.busid_set)
|
||||||
ERR_EXIT("The \"ccw\" target requires device");
|
ERR_EXIT("The \"ccw\" target requires device");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_eckd_opts(void)
|
||||||
|
{
|
||||||
|
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.fid_set)
|
||||||
|
ERR_EXIT("Invalid option for \"eckd\" target specified");
|
||||||
|
if (!(l.busid_set))
|
||||||
|
ERR_EXIT("The \"eckd\" target requires device");
|
||||||
|
}
|
||||||
|
|
||||||
static void check_nss_opts(void)
|
static void check_nss_opts(void)
|
||||||
{
|
{
|
||||||
if (l.bootprog_set || l.loadparm_set || l.busid_set || l.wwpn_set ||
|
if (l.bootprog_set || l.loadparm_set || l.busid_set || l.wwpn_set ||
|
||||||
l.lun_set)
|
l.lun_set || l.brchr_set)
|
||||||
ERR_EXIT("Invalid option for \"nss\" target specified");
|
ERR_EXIT("Invalid option for \"nss\" target specified");
|
||||||
if (!l.nss_name_set)
|
if (!l.nss_name_set)
|
||||||
ERR_EXIT("The \"nss\" target requires NSS name");
|
ERR_EXIT("The \"nss\" target requires NSS name");
|
||||||
@@ -563,6 +606,12 @@ static void set_reipl_clear(const char *arg)
|
|||||||
ERR_EXIT("re-IPL clear argument must be either 1 or 0");
|
ERR_EXIT("re-IPL clear argument must be either 1 or 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_brchr(const char *arg)
|
||||||
|
{
|
||||||
|
l.brchr = strdup(arg);
|
||||||
|
l.brchr_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_chreipl_options(int argc, char *argv[])
|
static void parse_chreipl_options(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int opt, idx;
|
int opt, idx;
|
||||||
@@ -580,6 +629,7 @@ static void parse_chreipl_options(int argc, char *argv[])
|
|||||||
{ "force", no_argument, NULL, 'f' },
|
{ "force", no_argument, NULL, 'f' },
|
||||||
{ "version", no_argument, NULL, 'v' },
|
{ "version", no_argument, NULL, 'v' },
|
||||||
{ "clear", required_argument, NULL, 'c' },
|
{ "clear", required_argument, NULL, 'c' },
|
||||||
|
{ "brchr", required_argument, NULL, OPT_BRCHR },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:i:s:";
|
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:i:s:";
|
||||||
@@ -592,6 +642,8 @@ static void parse_chreipl_options(int argc, char *argv[])
|
|||||||
set_target_type(TT_FCP, 0);
|
set_target_type(TT_FCP, 0);
|
||||||
else if (strcmp(argv[1], "ccw") == 0)
|
else if (strcmp(argv[1], "ccw") == 0)
|
||||||
set_target_type(TT_CCW, 0);
|
set_target_type(TT_CCW, 0);
|
||||||
|
else if (strcmp(argv[1], "eckd") == 0)
|
||||||
|
set_target_type(TT_ECKD, 0);
|
||||||
else if (strcmp(argv[1], "nss") == 0)
|
else if (strcmp(argv[1], "nss") == 0)
|
||||||
set_target_type(TT_NSS, 0);
|
set_target_type(TT_NSS, 0);
|
||||||
else if (strcmp(argv[1], "nvme") == 0)
|
else if (strcmp(argv[1], "nvme") == 0)
|
||||||
@@ -640,6 +692,9 @@ static void parse_chreipl_options(int argc, char *argv[])
|
|||||||
case 'c':
|
case 'c':
|
||||||
set_reipl_clear(optarg);
|
set_reipl_clear(optarg);
|
||||||
break;
|
break;
|
||||||
|
case OPT_BRCHR:
|
||||||
|
set_brchr(optarg);
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
print_version_exit();
|
print_version_exit();
|
||||||
default:
|
default:
|
||||||
@@ -737,6 +792,34 @@ static void chreipl_ccw(void)
|
|||||||
print_ccw(0);
|
print_ccw(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void chreipl_eckd(void)
|
||||||
|
{
|
||||||
|
check_eckd_opts();
|
||||||
|
|
||||||
|
if (!ccw_is_device(l.busid) && !l.force_set) {
|
||||||
|
if (is_ignored(l.busid))
|
||||||
|
ERR_EXIT("Device is on cio_ignore list, try \"cio_ignore -r %s\"?",
|
||||||
|
l.busid);
|
||||||
|
ERR_EXIT("Could not find DASD ECKD device \"%s\"", l.busid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l.reipl_clear >= 0) {
|
||||||
|
check_exists("reipl/eckd/clear", "ECKD re-IPL clear attribute");
|
||||||
|
write_str(l.reipl_clear ? "1" : "0", "reipl/eckd/clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!l.brchr_set)
|
||||||
|
l.brchr = "auto";
|
||||||
|
write_str(l.brchr, "reipl/eckd/br_chr");
|
||||||
|
if (!l.bootprog_set)
|
||||||
|
sprintf(l.bootprog, "0");
|
||||||
|
write_str(l.bootprog, "reipl/eckd/bootprog");
|
||||||
|
write_str(l.busid, "reipl/eckd/device");
|
||||||
|
write_str_optional(l.loadparm, "reipl/eckd/loadparm", l.loadparm_set, "loadparm");
|
||||||
|
write_str("eckd", "reipl/reipl_type");
|
||||||
|
print_eckd(0, "eckd");
|
||||||
|
}
|
||||||
|
|
||||||
static void chreipl_fcp(void)
|
static void chreipl_fcp(void)
|
||||||
{
|
{
|
||||||
check_fcp_opts();
|
check_fcp_opts();
|
||||||
@@ -850,6 +933,11 @@ static void chreipl_node(void)
|
|||||||
l.busid_set = 1;
|
l.busid_set = 1;
|
||||||
chreipl_ccw();
|
chreipl_ccw();
|
||||||
break;
|
break;
|
||||||
|
case REIPL_ECKD:
|
||||||
|
ccw_busid_get(l.dev, l.busid);
|
||||||
|
l.busid_set = 1;
|
||||||
|
chreipl_eckd();
|
||||||
|
break;
|
||||||
case REIPL_FCP:
|
case REIPL_FCP:
|
||||||
fcp_wwpn_get(l.dev, l.wwpn);
|
fcp_wwpn_get(l.dev, l.wwpn);
|
||||||
l.wwpn_set = 1;
|
l.wwpn_set = 1;
|
||||||
@@ -878,6 +966,9 @@ void cmd_chreipl(int argc, char *argv[])
|
|||||||
case TT_CCW:
|
case TT_CCW:
|
||||||
chreipl_ccw();
|
chreipl_ccw();
|
||||||
break;
|
break;
|
||||||
|
case TT_ECKD:
|
||||||
|
chreipl_eckd();
|
||||||
|
break;
|
||||||
case TT_FCP:
|
case TT_FCP:
|
||||||
chreipl_fcp();
|
chreipl_fcp();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -141,6 +141,30 @@ void print_ccw(int show_ipl)
|
|||||||
print_fw_str("clear: %s\n", dir, "clear");
|
print_fw_str("clear: %s\n", dir, "clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_eckd(int show_ipl, const char *name)
|
||||||
|
{
|
||||||
|
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
|
||||||
|
"/sys/firmware/reipl/eckd/loadparm";
|
||||||
|
char *dir = show_ipl ? "ipl" : "reipl/eckd";
|
||||||
|
char loadparm[9], loadparm_path[PATH_MAX];
|
||||||
|
|
||||||
|
printf("%-12s %s\n", get_ipl_banner(show_ipl), name);
|
||||||
|
|
||||||
|
print_fw_str("Device: %s\n", dir, "device");
|
||||||
|
print_fw_str("bootprog: %s\n", dir, "bootprog");
|
||||||
|
print_fw_str("br_chr: %s\n", dir, "br_chr");
|
||||||
|
print_fw_str("Bootparm: \"%s\"\n", dir, "scp_data");
|
||||||
|
if (access(path_loadparm, R_OK) == 0) {
|
||||||
|
sprintf(loadparm_path, "%s/%s", dir, "loadparm");
|
||||||
|
read_fw_str(loadparm, loadparm_path, sizeof(loadparm));
|
||||||
|
if (strcmp(loadparm, " ") == 0)
|
||||||
|
loadparm[0] = 0;
|
||||||
|
printf("Loadparm: \"%s\"\n", loadparm);
|
||||||
|
}
|
||||||
|
if (!show_ipl)
|
||||||
|
print_fw_str("clear: %s\n", dir, "clear");
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_lsreipl_options(int argc, char *argv[])
|
static void parse_lsreipl_options(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int opt, idx;
|
int opt, idx;
|
||||||
@@ -193,6 +217,9 @@ void cmd_lsreipl(int argc, char *argv[])
|
|||||||
print_nvme(l.ipl_set, 1);
|
print_nvme(l.ipl_set, 1);
|
||||||
else if (strcmp(reipl_type_str, "ccw") == 0)
|
else if (strcmp(reipl_type_str, "ccw") == 0)
|
||||||
print_ccw(l.ipl_set);
|
print_ccw(l.ipl_set);
|
||||||
|
else if (strcmp(reipl_type_str, "eckd") == 0 ||
|
||||||
|
strcmp(reipl_type_str, "eckd_dump") == 0)
|
||||||
|
print_eckd(l.ipl_set, reipl_type_str);
|
||||||
else if (strcmp(reipl_type_str, "nss") == 0)
|
else if (strcmp(reipl_type_str, "nss") == 0)
|
||||||
print_nss(l.ipl_set);
|
print_nss(l.ipl_set);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ extern void print_ccw(int show_ipl);
|
|||||||
extern void print_fcp(int show_ipl, int dump);
|
extern void print_fcp(int show_ipl, int dump);
|
||||||
extern void print_nvme(int show_ipl, int dump);
|
extern void print_nvme(int show_ipl, int dump);
|
||||||
extern void print_nss(int show_ipl);
|
extern void print_nss(int show_ipl);
|
||||||
|
extern void print_eckd(int show_ipl, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper
|
* Helper
|
||||||
@@ -75,6 +76,7 @@ extern void fcp_busid_get(const char *device, char *devno);
|
|||||||
* NVME
|
* NVME
|
||||||
*/
|
*/
|
||||||
#define FID_MAX_LEN 11 /* 8 characters + 0x + null */
|
#define FID_MAX_LEN 11 /* 8 characters + 0x + null */
|
||||||
|
#define NVME_DEV_MAX_LEN 15 /* "nvme" + u32 in decimal + null */
|
||||||
#define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1)
|
#define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1)
|
||||||
|
|
||||||
extern void nvme_fid_get(const char *device, char *fid);
|
extern void nvme_fid_get(const char *device, char *fid);
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ The first argument specifies the re-IPL target:
|
|||||||
.RB "- " ccw :
|
.RB "- " ccw :
|
||||||
Specify a DASD CCW device for reboot
|
Specify a DASD CCW device for reboot
|
||||||
.TP
|
.TP
|
||||||
|
.RB "- " eckd :
|
||||||
|
Specify a DASD ECKD device for reboot
|
||||||
|
.TP
|
||||||
.RB "- " fcp :
|
.RB "- " fcp :
|
||||||
Specify a FCP device for reboot
|
Specify a FCP device for reboot
|
||||||
.TP
|
.TP
|
||||||
@@ -175,6 +178,63 @@ in the installed zIPL environment block for evaluation of zIPL environment
|
|||||||
variables in the kernel command line:
|
variables in the kernel command line:
|
||||||
|
|
||||||
\fB# chreipl ccw -d 0.0.7e78 -L 1S2\fP
|
\fB# chreipl ccw -d 0.0.7e78 -L 1S2\fP
|
||||||
|
|
||||||
|
.SH eckd
|
||||||
|
Use the eckd re-IPL target for DASD devices that are accessed by the hardware
|
||||||
|
using channel command word (CCW) channels. In contrast to the ccw re-IPL target,
|
||||||
|
the eckd target uses a list-directed bootloader that supports secure boot.
|
||||||
|
.TP
|
||||||
|
.BR "\-d" " or " "\-\-device"
|
||||||
|
Specifies the device bus-ID of the DASD. If the bus-ID starts with "0.0." this
|
||||||
|
prefix can be omitted and the four digit short notation can be used (e.g. 5000 is
|
||||||
|
the same as 0.0.5000).
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-b" " or " "\-\-bootprog"
|
||||||
|
Specifies an entry in the ECKD boot configuration by defining the IPL boot
|
||||||
|
program selector. If omitted, '0' is used.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-\-brchr"
|
||||||
|
Specifies the block on the DASD where the boot record is located. If omitted,
|
||||||
|
0 is used. The specification comprises comma-separated values for cylinder, head,
|
||||||
|
and record: "--brchr C,H,R". Alternatively, specifying "0" or "auto" makes the
|
||||||
|
bootloader determine the boot record location from the volume label.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-L" " or " "\-\-loadparm"
|
||||||
|
The loadparm for the eckd re-IPL target is not used to control the ECKD boot
|
||||||
|
configuration that is defined by the
|
||||||
|
.BR zipl (8)
|
||||||
|
boot menu. Instead it can be used to control higher level boot loaders
|
||||||
|
like GRUB. For more details refer to distribution specific documentation.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-c" " or " "\-\-clear"
|
||||||
|
Controls whether memory is cleared on re-IPL. Possible values are 0 to
|
||||||
|
disable and 1 to enable memory clearing on re-IPL.
|
||||||
|
Memory clearing is supported if the "clear" attribute is present in
|
||||||
|
/sys/firmware/reipl/eckd/.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fBExamples:\fP
|
||||||
|
.br
|
||||||
|
|
||||||
|
1. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
|
||||||
|
program selector 0:
|
||||||
|
|
||||||
|
\fB# chreipl eckd 0.0.7e78\fP
|
||||||
|
|
||||||
|
2. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
|
||||||
|
program selector 2:
|
||||||
|
|
||||||
|
\fB# chreipl eckd -d 0.0.7e78 -b 2\fP
|
||||||
|
|
||||||
|
3. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and tell
|
||||||
|
the bootloader that the bootrecord is located in Cylinder 3, Head 0, Record 1:
|
||||||
|
|
||||||
|
\fB# chreipl eckd -d 0.0.7e78 --brchr 3,0,1\fP
|
||||||
|
|
||||||
.SH fcp
|
.SH fcp
|
||||||
Use the fcp re-IPL target for SCSI disks that are accessed by the hardware
|
Use the fcp re-IPL target for SCSI disks that are accessed by the hardware
|
||||||
using Fibre Channel Protocol (FCP) channels.
|
using Fibre Channel Protocol (FCP) channels.
|
||||||
|
|||||||
@@ -18,15 +18,31 @@
|
|||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
#include "ipl_tools.h"
|
#include "ipl_tools.h"
|
||||||
|
|
||||||
|
static void nvme_dev_from_bdev(char *dev_name)
|
||||||
|
{
|
||||||
|
char *delim = strrchr(dev_name, 'n');
|
||||||
|
|
||||||
|
if (delim)
|
||||||
|
*delim = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the fid of a device
|
* Return the fid of a device
|
||||||
*/
|
*/
|
||||||
void nvme_fid_get(const char *device, char *fid)
|
void nvme_fid_get(const char *device, char *fid)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX], buf[FID_MAX_LEN];
|
char path[PATH_MAX], buf[FID_MAX_LEN];
|
||||||
|
char nvme_dev[NVME_DEV_MAX_LEN];
|
||||||
|
|
||||||
snprintf(path, PATH_MAX, "/sys/block/%s/device/device/function_id",
|
/*
|
||||||
device);
|
* An NVMe may present multiple namespaces and thus block devices, even
|
||||||
|
* before partitioning, so we need the nvme<NUM> part of the block
|
||||||
|
* device name to get to the PCI function ID.
|
||||||
|
*/
|
||||||
|
util_strlcpy(nvme_dev, device, sizeof(nvme_dev));
|
||||||
|
nvme_dev_from_bdev(nvme_dev);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/nvme/%s/device/function_id", nvme_dev);
|
||||||
if (util_file_read_line(buf, FID_MAX_LEN, path))
|
if (util_file_read_line(buf, FID_MAX_LEN, path))
|
||||||
ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
|
ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# z/VM IUCV HVC device driver -- Edit z/VM user ID filter
|
# z/VM IUCV HVC device driver -- Edit z/VM user ID filter
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ extern ssize_t __write(int, const void*, size_t);
|
|||||||
extern int strmatch(const char *, const char *);
|
extern int strmatch(const char *, const char *);
|
||||||
extern int is_regex_valid(const char *);
|
extern int is_regex_valid(const char *);
|
||||||
extern int is_client_allowed(const char *, const struct iucvterm_cfg *);
|
extern int is_client_allowed(const char *, const struct iucvterm_cfg *);
|
||||||
extern void userid_cpy(char [8], const char [8]);
|
extern void userid_cpy(char [9], const char [8]);
|
||||||
|
|
||||||
extern void iucv_msg_error(const char *, uint32_t);
|
extern void iucv_msg_error(const char *, uint32_t);
|
||||||
extern void program_error(const char *, const char *);
|
extern void program_error(const char *, const char *);
|
||||||
|
|||||||
@@ -2,17 +2,6 @@ include ../common.mak
|
|||||||
|
|
||||||
lib = libap.a
|
lib = libap.a
|
||||||
|
|
||||||
check-dep-lock:
|
|
||||||
touch check-dep-lock
|
|
||||||
ifneq (${HAVE_LOCKFILE},0)
|
|
||||||
$(call check_dep, \
|
|
||||||
"libap", \
|
|
||||||
"lockfile.h", \
|
|
||||||
"liblockfile-devel", \
|
|
||||||
"HAVE_LOCKFILE=0")
|
|
||||||
ALL_CPPFLAGS += -DHAVE_LOCKFILE
|
|
||||||
endif
|
|
||||||
|
|
||||||
check-dep-json:
|
check-dep-json:
|
||||||
touch check-dep-json
|
touch check-dep-json
|
||||||
ifneq (${HAVE_JSONC},0)
|
ifneq (${HAVE_JSONC},0)
|
||||||
@@ -29,7 +18,7 @@ objects = ap.o
|
|||||||
|
|
||||||
$(lib): $(objects)
|
$(lib): $(objects)
|
||||||
|
|
||||||
$(objects): check-dep-lock check-dep-json
|
$(objects): check-dep-json
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
|
||||||
|
|||||||
45
libap/ap.c
45
libap/ap.c
@@ -22,13 +22,10 @@
|
|||||||
#include <json-c/json.h>
|
#include <json-c/json.h>
|
||||||
#endif /* HAVE_JSONC */
|
#endif /* HAVE_JSONC */
|
||||||
|
|
||||||
#ifdef HAVE_LOCKFILE
|
|
||||||
#include <lockfile.h>
|
|
||||||
#endif /* HAVE_LOCKFILE */
|
|
||||||
|
|
||||||
#include "lib/ap.h"
|
#include "lib/ap.h"
|
||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
#include "lib/util_libc.h"
|
#include "lib/util_libc.h"
|
||||||
|
#include "lib/util_lockfile.h"
|
||||||
#include "lib/util_panic.h"
|
#include "lib/util_panic.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
#include "lib/util_udev.h"
|
#include "lib/util_udev.h"
|
||||||
@@ -701,33 +698,28 @@ void ap_list_remove_all(struct util_list *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LOCKFILE
|
|
||||||
static int ap_lockfile_create(int flags)
|
|
||||||
{
|
|
||||||
return lockfile_create(AP_LOCKFILE, AP_LOCK_RETRIES, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire the ap config lock using this process PID (L_PID)
|
* Acquire the ap config lock using this Process ID
|
||||||
|
*
|
||||||
|
* @retval 0 Lock acquired on behalf of this process
|
||||||
*
|
*
|
||||||
* @retval 0 Lock successfully acquired on behalf of L_PID
|
|
||||||
* @retval != 0 Error, lock was not obtained
|
* @retval != 0 Error, lock was not obtained
|
||||||
*/
|
*/
|
||||||
int ap_get_lock(void)
|
int ap_get_lock(void)
|
||||||
{
|
{
|
||||||
return ap_lockfile_create(L_PID);
|
return util_lockfile_lock(AP_LOCKFILE, AP_LOCK_RETRIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire the ap config lock using the parent process PID (L_PPID) -- intended
|
* Acquire the ap config lock using the Parent Process ID -- intended for use
|
||||||
* for use by the mdevctl callout ap-check utility
|
* by the mdevctl callout ap-check utility
|
||||||
*
|
*
|
||||||
* @retval 0 Lock successfully acquired on behalf of L_PPID
|
* @retval 0 Lock acquired on behalf of parent process
|
||||||
* @retval != 0 Error, lock was not obtained
|
* @retval != 0 Error, lock was not obtained
|
||||||
*/
|
*/
|
||||||
int ap_get_lock_callout(void)
|
int ap_get_lock_callout(void)
|
||||||
{
|
{
|
||||||
return ap_lockfile_create(L_PPID);
|
return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -738,23 +730,10 @@ int ap_get_lock_callout(void)
|
|||||||
*/
|
*/
|
||||||
int ap_release_lock(void)
|
int ap_release_lock(void)
|
||||||
{
|
{
|
||||||
return lockfile_remove(AP_LOCKFILE);
|
return util_lockfile_release(AP_LOCKFILE);
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* If no liblockfile, actions are performed without acquiring the file lock */
|
|
||||||
int ap_get_lock(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ap_get_lock_callout(void)
|
int ap_release_lock_callout(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return util_lockfile_parent_release(AP_LOCKFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ap_release_lock(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_LOCKFILE */
|
|
||||||
|
|||||||
@@ -85,5 +85,6 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("PAI NNPA support %d\n", libcpumf_have_pai_nnpa());
|
printf("PAI NNPA support %d\n", libcpumf_have_pai_nnpa());
|
||||||
|
printf("PAI EXTENSION support %d\n", libcpumf_have_pai_ext());
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,13 @@ bool libcpumf_have_pai_crypto(void)
|
|||||||
return (stat(S390_SYSFS_PAI_CRYPTO, &statbuf) == -1) ? false : true;
|
return (stat(S390_SYSFS_PAI_CRYPTO, &statbuf) == -1) ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool libcpumf_have_pai_ext(void)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
return (stat(S390_SYSFS_PAI_EXT, &statbuf) == -1) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
bool libcpumf_have_pai_nnpa(void)
|
bool libcpumf_have_pai_nnpa(void)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "lib/dasd_base.h"
|
#include "lib/dasd_base.h"
|
||||||
|
|
||||||
@@ -27,11 +29,13 @@
|
|||||||
|
|
||||||
#define RUN_IOCTL(fd, req, argp) \
|
#define RUN_IOCTL(fd, req, argp) \
|
||||||
do { \
|
do { \
|
||||||
if (ioctl(fd, req, argp) != 0) { \
|
int rc = ioctl(fd, req, argp); \
|
||||||
int err = errno; \
|
if (rc != 0) { \
|
||||||
if (err != EBADF) \
|
if (rc == -1) \
|
||||||
|
rc = errno; \
|
||||||
|
if (rc != EBADF) \
|
||||||
dasd_close_device(fd); \
|
dasd_close_device(fd); \
|
||||||
return err; \
|
return rc; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@@ -321,3 +325,159 @@ int dasd_disk_release(const char *device)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unconditionally reserve DASD disk
|
||||||
|
*
|
||||||
|
* An existing reserve lock is lifted (steal lock) and the device
|
||||||
|
* is reserved.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_slock(const char *device)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDSLCK, NULL);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the caching algorithm used for the channel programs of this device.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
* @param[out] attrib_data pointer to dasd attrib data with:
|
||||||
|
* 'cache' is the caching mode
|
||||||
|
* 'no_cyl' the number of cylinders to be cached.
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_get_cache(const char *device, attrib_data_t *attrib_data)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDGATTR, attrib_data);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the caching algorithm used for the channel programs of this device.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
* @param[in] attrib_data pointer to dasd attrib data with:
|
||||||
|
* 'cache' is the caching mode
|
||||||
|
* 'no_cyl' the number of cylinders to be cached.
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_set_cache(const char *device, attrib_data_t *attrib_data)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDSATTR, attrib_data);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get reserve status of device.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
*
|
||||||
|
* @retval errno in case of failure
|
||||||
|
* @retval 0 unreserved
|
||||||
|
* @retval 1 implicit reserved
|
||||||
|
* @retval 2 other reservation
|
||||||
|
* @retval 3 reserved
|
||||||
|
*/
|
||||||
|
int dasd_query_reserve(const char *device)
|
||||||
|
{
|
||||||
|
struct dasd_snid_ioctl_data snid = { 0 };
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDSNID, &snid);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return snid.data.path_state.reserve;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get and print the profiling info of the device.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
* @param[in] dasd_profile_info pointer to dasd profile info
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDPRRD, dasd_profile_info);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the profiling counters of the device.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_reset_profile(const char *device)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDPRRST, NULL);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initiate the swap of a copy pairs primary,secondary relation.
|
||||||
|
* The old secondary will become the new primary and vice versa.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
* @param[in] copy_pair data pointer to dasd copypair data with:
|
||||||
|
* 'primary' old primary, becoming secondary
|
||||||
|
* 'secondary' old secondary, becoming primary.
|
||||||
|
*
|
||||||
|
* @retval errno in case of failure
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval 1 swap data invalid
|
||||||
|
* @retval 2 no active device found
|
||||||
|
* @retval 3 wrong primary specified
|
||||||
|
* @retval 4 secondary device not found
|
||||||
|
* @retval 5 swap already running
|
||||||
|
*/
|
||||||
|
int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDPPRCSWAP, data);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,21 +5,12 @@ include ../common.mak
|
|||||||
|
|
||||||
LIB := libpv.a
|
LIB := libpv.a
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto openssl)
|
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto openssl)
|
LIBCURL_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
LIBCURL_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
|
||||||
else
|
|
||||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
|
||||||
GLIB2_LIBS := -lglib-2.0
|
|
||||||
LIBCRYPTO_CFLAGS :=
|
|
||||||
LIBCRYPTO_LIBS := -lcrypto -lssl
|
|
||||||
LIBCURL_CFLAGS := -I/usr/include/s390x-linux-gnu
|
|
||||||
LIBCURL_LIBS := -lcurl
|
|
||||||
endif
|
|
||||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||||
|
|
||||||
WARNINGS := -Wall -Wextra -Wshadow \
|
WARNINGS := -Wall -Wextra -Wshadow \
|
||||||
@@ -28,7 +19,6 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
|||||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||||
-Wpointer-arith -Wno-error=inline \
|
-Wpointer-arith -Wno-error=inline \
|
||||||
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
|
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
|
||||||
-Werror \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ALL_CFLAGS += -std=gnu11 \
|
ALL_CFLAGS += -std=gnu11 \
|
||||||
@@ -51,7 +41,7 @@ endif
|
|||||||
sources := $(wildcard *.c)
|
sources := $(wildcard *.c)
|
||||||
objects := $(patsubst %.c,%.o,$(sources))
|
objects := $(patsubst %.c,%.o,$(sources))
|
||||||
|
|
||||||
all: $(BUILD_TARGETS) .check_dep-$(LIB)
|
all: $(BUILD_TARGETS)
|
||||||
|
|
||||||
$(LIB): $(objects)
|
$(LIB): $(objects)
|
||||||
$(LIB): ALL_CFLAGS += -fPIC
|
$(LIB): ALL_CFLAGS += -fPIC
|
||||||
@@ -74,7 +64,7 @@ skip-$(LIB):
|
|||||||
.detect-openssl.dep.c:
|
.detect-openssl.dep.c:
|
||||||
echo "#include <openssl/evp.h>" > $@
|
echo "#include <openssl/evp.h>" > $@
|
||||||
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> $@
|
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> $@
|
||||||
echo " #error openssl version 1.1.0 is required" >> $@
|
echo " #error openssl version 1.1.1 is required" >> $@
|
||||||
echo "#endif" >> $@
|
echo "#endif" >> $@
|
||||||
echo "static void __attribute__((unused)) test(void) {" >> $@
|
echo "static void __attribute__((unused)) test(void) {" >> $@
|
||||||
echo " EVP_MD_CTX *ctx = EVP_MD_CTX_new();" >> $@
|
echo " EVP_MD_CTX *ctx = EVP_MD_CTX_new();" >> $@
|
||||||
@@ -90,7 +80,7 @@ skip-$(LIB):
|
|||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"$(LIB)", \
|
"$(LIB)", \
|
||||||
$^, \
|
$^, \
|
||||||
"openssl-devel / libssl-dev version >= 1.1.0", \
|
"openssl-devel / libssl-dev version >= 1.1.1", \
|
||||||
"HAVE_OPENSSL=0", \
|
"HAVE_OPENSSL=0", \
|
||||||
"-I.")
|
"-I.")
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
|
|||||||
35
libpv/cert.c
35
libpv/cert.c
@@ -290,7 +290,9 @@ static char *pv_X509_NAME_oneline(const X509_NAME *name)
|
|||||||
long len;
|
long len;
|
||||||
|
|
||||||
if (X509_NAME_print_ex(key_bio, name, 0, XN_FLAG_RFC2253) == -1) {
|
if (X509_NAME_print_ex(key_bio, name, 0, XN_FLAG_RFC2253) == -1) {
|
||||||
g_warning(_("Cannot receive X509-NAME from CRL: %s"), pv_get_openssl_error());
|
g_autofree char *openssl_err_msg = pv_get_openssl_errors();
|
||||||
|
|
||||||
|
g_warning(_("Cannot receive X509-NAME from CRL: %s"), openssl_err_msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +494,9 @@ static X509_CRL *load_crl_by_dist_point(DIST_POINT *crldp, GError **error)
|
|||||||
X509_CRL *pv_load_first_crl_by_cert(X509 *cert, GError **error)
|
X509_CRL *pv_load_first_crl_by_cert(X509 *cert, GError **error)
|
||||||
{
|
{
|
||||||
g_autoptr(STACK_OF_DIST_POINT) crldps = NULL;
|
g_autoptr(STACK_OF_DIST_POINT) crldps = NULL;
|
||||||
|
g_autoptr(GError) last_error = NULL;
|
||||||
g_autoptr(X509_CRL) ret = NULL;
|
g_autoptr(X509_CRL) ret = NULL;
|
||||||
|
int dist_points_cnt;
|
||||||
|
|
||||||
g_assert(cert);
|
g_assert(cert);
|
||||||
|
|
||||||
@@ -503,19 +507,24 @@ X509_CRL *pv_load_first_crl_by_cert(X509 *cert, GError **error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sk_DIST_POINT_num(crldps); i++) {
|
dist_points_cnt = sk_DIST_POINT_num(crldps);
|
||||||
|
for (int i = 0; i < dist_points_cnt; i++) {
|
||||||
DIST_POINT *crldp = sk_DIST_POINT_value(crldps, i);
|
DIST_POINT *crldp = sk_DIST_POINT_value(crldps, i);
|
||||||
|
|
||||||
g_assert(crldp);
|
g_assert(crldp);
|
||||||
|
|
||||||
/* ignore error */
|
g_clear_error(&last_error);
|
||||||
ret = load_crl_by_dist_point(crldp, NULL);
|
ret = load_crl_by_dist_point(crldp, &last_error);
|
||||||
if (ret)
|
if (ret)
|
||||||
return g_steal_pointer(&ret);
|
return g_steal_pointer(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_FAILED_DOWNLOAD_CRL,
|
/* relabel error */
|
||||||
_("failed to download CRL"));
|
if (last_error)
|
||||||
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_FAILED_DOWNLOAD_CRL,
|
||||||
|
"%s", last_error->message);
|
||||||
|
else
|
||||||
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_FAILED_DOWNLOAD_CRL,
|
||||||
|
_("failed to download CRL"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,7 +792,7 @@ int pv_store_set_verify_param(X509_STORE *store, GError **error)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL,
|
||||||
_("X509 store initialization failed"));
|
_("X509 store initialization failed"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1368,14 +1377,14 @@ int pv_check_chain_parameters(const STACK_OF_X509 *chain, GError **error)
|
|||||||
|
|
||||||
ca_x509_subject = X509_get_subject_name(ca);
|
ca_x509_subject = X509_get_subject_name(ca);
|
||||||
if (!ca_x509_subject) {
|
if (!ca_x509_subject) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL,
|
||||||
_("subject of the root CA cannot be retrieved"));
|
_("subject of the root CA cannot be retrieved"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ca_subject = pv_X509_NAME_oneline(ca_x509_subject);
|
ca_subject = pv_X509_NAME_oneline(ca_x509_subject);
|
||||||
if (!ca_subject) {
|
if (!ca_subject) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL,
|
||||||
_("subject name of the root CA cannot be retrieved"));
|
_("subject name of the root CA cannot be retrieved"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1469,11 +1478,11 @@ static STACK_OF_X509 *get_ibm_signing_certs(STACK_OF_X509 *certs, GError **error
|
|||||||
ibm_signing_certs = pv_remove_ibm_signing_certs(certs);
|
ibm_signing_certs = pv_remove_ibm_signing_certs(certs);
|
||||||
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
|
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
|
||||||
if (ibm_signing_certs_count < 1) {
|
if (ibm_signing_certs_count < 1) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
_("Specify at least one IBM Z signing key"));
|
_("Specify at least one IBM Z signing key"));
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (ibm_signing_certs_count > 1) {
|
} else if (ibm_signing_certs_count > 1) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
_("Specify only one IBM Z signing key"));
|
_("Specify only one IBM Z signing key"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1504,7 +1513,7 @@ static gboolean download_crls(X509_STORE *trusted, PvCertWithPathList *host_key_
|
|||||||
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
|
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
|
||||||
|
|
||||||
if (X509_STORE_add_crl(trusted, crl) != 1) {
|
if (X509_STORE_add_crl(trusted, crl) != 1) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
|
g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL,
|
||||||
_("failed to load CRL"));
|
_("failed to load CRL"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,18 @@
|
|||||||
#include "libpv/glib-helper.h"
|
#include "libpv/glib-helper.h"
|
||||||
#include "libpv/hash.h"
|
#include "libpv/hash.h"
|
||||||
|
|
||||||
const char *pv_get_openssl_error(void)
|
char *pv_get_openssl_errors(void)
|
||||||
{
|
{
|
||||||
const char *ret;
|
char *ret;
|
||||||
BIO *bio;
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
BIO *bio;
|
||||||
long len;
|
long len;
|
||||||
|
|
||||||
bio = BIO_new(BIO_s_mem());
|
bio = BIO_new(BIO_s_mem());
|
||||||
ERR_print_errors(bio);
|
ERR_print_errors(bio);
|
||||||
len = BIO_get_mem_data(bio, &buf);
|
len = BIO_get_mem_data(bio, &buf);
|
||||||
if (len < 0)
|
if (len <= 0 || !buf)
|
||||||
ret = "Cannot receive OpenSSL error message.";
|
ret = g_strdup("Cannot receive OpenSSL error message.");
|
||||||
else
|
else
|
||||||
ret = g_strndup(buf, (size_t)len);
|
ret = g_strndup(buf, (size_t)len);
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
@@ -41,7 +41,7 @@ int pv_BIO_reset(BIO *b)
|
|||||||
{
|
{
|
||||||
int rc = BIO_reset(b);
|
int rc = BIO_reset(b);
|
||||||
|
|
||||||
if (rc != 1 && (BIO_method_type(b) == BIO_TYPE_FILE && rc != 0))
|
if (rc != 1 && !(BIO_method_type(b) == BIO_TYPE_FILE && rc == 0))
|
||||||
return -1;
|
return -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ int64_t pv_gcm_decrypt(GBytes *cipher, GBytes *aad, GBytes *tag, const PvCipherP
|
|||||||
}
|
}
|
||||||
|
|
||||||
GBytes *pv_hkdf_extract_and_expand(size_t derived_key_len, GBytes *key, GBytes *salt, GBytes *info,
|
GBytes *pv_hkdf_extract_and_expand(size_t derived_key_len, GBytes *key, GBytes *salt, GBytes *info,
|
||||||
const EVP_MD *md, G_GNUC_UNUSED GError **error)
|
const EVP_MD *md, GError **error)
|
||||||
{
|
{
|
||||||
const unsigned char *salt_data, *key_data, *info_data;
|
const unsigned char *salt_data, *key_data, *info_data;
|
||||||
g_autoptr(EVP_PKEY_CTX) ctx = NULL;
|
g_autoptr(EVP_PKEY_CTX) ctx = NULL;
|
||||||
@@ -354,7 +354,6 @@ GBytes *pv_hkdf_extract_and_expand(size_t derived_key_len, GBytes *key, GBytes *
|
|||||||
if (EVP_PKEY_derive(ctx, derived_key, &derived_key_len) != 1) {
|
if (EVP_PKEY_derive(ctx, derived_key, &derived_key_len) != 1) {
|
||||||
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_HKDF_FAIL,
|
g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_HKDF_FAIL,
|
||||||
"FAILED to derive key via HKDF");
|
"FAILED to derive key via HKDF");
|
||||||
printf("%s\n", pv_get_openssl_error());
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,12 +168,14 @@ GBytes *pv_file_get_content_as_secure_bytes(const char *filename)
|
|||||||
return pv_sec_gbytes_new_take(g_steal_pointer(&data), data_size);
|
return pv_sec_gbytes_new_take(g_steal_pointer(&data), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src)
|
void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied)
|
||||||
{
|
{
|
||||||
size_t src_size;
|
size_t src_size;
|
||||||
const void *src_data = g_bytes_get_data(src, &src_size);
|
const void *src_data = g_bytes_get_data(src, &src_size);
|
||||||
|
|
||||||
if (dst_size < src_size)
|
if (dst_size < src_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (copied)
|
||||||
|
*copied = src_size;
|
||||||
return memcpy(dst, src_data, src_size);
|
return memcpy(dst, src_data, src_size);
|
||||||
}
|
}
|
||||||
|
|||||||
12
libpv/hash.c
12
libpv/hash.c
@@ -97,8 +97,10 @@ HMAC_CTX *pv_hmac_ctx_new(GBytes *key, const EVP_MD *md, GError **error)
|
|||||||
key_data = g_bytes_get_data(key, &key_size);
|
key_data = g_bytes_get_data(key, &key_size);
|
||||||
|
|
||||||
if (HMAC_Init_ex(ctx, key_data, (int)key_size, md, NULL) != 1) {
|
if (HMAC_Init_ex(ctx, key_data, (int)key_size, md, NULL) != 1) {
|
||||||
|
g_autofree char *openssl_err_msg = pv_get_openssl_errors();
|
||||||
|
|
||||||
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
||||||
"unable to create HMAC context: %s", pv_get_openssl_error());
|
"unable to create HMAC context: %s", openssl_err_msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return g_steal_pointer(&ctx);
|
return g_steal_pointer(&ctx);
|
||||||
@@ -110,8 +112,10 @@ int pv_hmac_ctx_update_raw(HMAC_CTX *ctx, const void *buf, size_t size, GError *
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (HMAC_Update(ctx, buf, size) != 1) {
|
if (HMAC_Update(ctx, buf, size) != 1) {
|
||||||
|
g_autofree char *openssl_err_msg = pv_get_openssl_errors();
|
||||||
|
|
||||||
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
||||||
"unable to add data to HMAC context: %s", pv_get_openssl_error());
|
"unable to add data to HMAC context: %s", openssl_err_msg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -139,8 +143,10 @@ GBytes *pv_hamc_ctx_finalize(HMAC_CTX *ctx, GError **error)
|
|||||||
hmac = g_malloc0((unsigned int)md_size);
|
hmac = g_malloc0((unsigned int)md_size);
|
||||||
|
|
||||||
if (HMAC_Final(ctx, hmac, &hmac_size) != 1) {
|
if (HMAC_Final(ctx, hmac, &hmac_size) != 1) {
|
||||||
|
g_autofree char *openssl_err_msg = pv_get_openssl_errors();
|
||||||
|
|
||||||
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL,
|
||||||
"unable to calculate HMAC: %s", pv_get_openssl_error());
|
"unable to calculate HMAC: %s", openssl_err_msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return g_bytes_new_take(g_steal_pointer(&hmac), hmac_size);
|
return g_bytes_new_take(g_steal_pointer(&hmac), hmac_size);
|
||||||
|
|||||||
@@ -174,6 +174,20 @@ static OSSL_FUNC_keymgmt_settable_params_fn
|
|||||||
sk_prov_keymgmt_rsa_pss_settable_params;
|
sk_prov_keymgmt_rsa_pss_settable_params;
|
||||||
static OSSL_FUNC_keymgmt_settable_params_fn
|
static OSSL_FUNC_keymgmt_settable_params_fn
|
||||||
sk_prov_keymgmt_ec_settable_params;
|
sk_prov_keymgmt_ec_settable_params;
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||||
|
sk_prov_keymgmt_rsa_export_types_ex;
|
||||||
|
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||||
|
sk_prov_keymgmt_rsa_pss_export_types_ex;
|
||||||
|
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||||
|
sk_prov_keymgmt_ec_export_types_ex;
|
||||||
|
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||||
|
sk_prov_keymgmt_rsa_import_types_ex;
|
||||||
|
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||||
|
sk_prov_keymgmt_rsa_pss_import_types_ex;
|
||||||
|
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||||
|
sk_prov_keymgmt_ec_import_types_ex;
|
||||||
|
#else
|
||||||
static OSSL_FUNC_keymgmt_export_types_fn
|
static OSSL_FUNC_keymgmt_export_types_fn
|
||||||
sk_prov_keymgmt_rsa_export_types;
|
sk_prov_keymgmt_rsa_export_types;
|
||||||
static OSSL_FUNC_keymgmt_export_types_fn
|
static OSSL_FUNC_keymgmt_export_types_fn
|
||||||
@@ -185,6 +199,7 @@ static OSSL_FUNC_keymgmt_import_types_fn
|
|||||||
static OSSL_FUNC_keymgmt_import_types_fn
|
static OSSL_FUNC_keymgmt_import_types_fn
|
||||||
sk_prov_keymgmt_rsa_pss_import_types;
|
sk_prov_keymgmt_rsa_pss_import_types;
|
||||||
static OSSL_FUNC_keymgmt_import_types_fn sk_prov_keymgmt_ec_import_types;
|
static OSSL_FUNC_keymgmt_import_types_fn sk_prov_keymgmt_ec_import_types;
|
||||||
|
#endif
|
||||||
|
|
||||||
static OSSL_FUNC_keyexch_newctx_fn sk_prov_keyexch_ec_newctx;
|
static OSSL_FUNC_keyexch_newctx_fn sk_prov_keyexch_ec_newctx;
|
||||||
static OSSL_FUNC_keyexch_dupctx_fn sk_prov_keyexch_ec_dupctx;
|
static OSSL_FUNC_keyexch_dupctx_fn sk_prov_keyexch_ec_dupctx;
|
||||||
@@ -552,6 +567,33 @@ static const OSSL_PARAM *sk_prov_cached_params_build(
|
|||||||
return provctx->cached_parms[index];
|
return provctx->cached_parms[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
static bool sk_prov_check_uint_param(const OSSL_PARAM params[],
|
||||||
|
const char *param_name,
|
||||||
|
const struct sk_prov_key *key,
|
||||||
|
int key_type,
|
||||||
|
unsigned int expected_value)
|
||||||
|
{
|
||||||
|
const OSSL_PARAM *p;
|
||||||
|
unsigned int value;
|
||||||
|
|
||||||
|
if (key == NULL)
|
||||||
|
return true;
|
||||||
|
if (key->type != key_type)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
p = OSSL_PARAM_locate_const(params, param_name);
|
||||||
|
if (p == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (OSSL_PARAM_get_uint(p, &value) != 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return value == expected_value;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
static struct sk_prov_op_ctx *sk_prov_op_newctx(struct sk_prov_ctx *provctx,
|
static struct sk_prov_op_ctx *sk_prov_op_newctx(struct sk_prov_ctx *provctx,
|
||||||
const char *propq,
|
const char *propq,
|
||||||
int type)
|
int type)
|
||||||
@@ -850,6 +892,20 @@ static int sk_prov_asym_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|||||||
for (p = params; p != NULL && p->key != NULL; p++)
|
for (p = params; p != NULL && p->key != NULL; p++)
|
||||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||||
|
|
||||||
|
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||||
|
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
|
||||||
|
if (!sk_prov_check_uint_param(params,
|
||||||
|
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||||
|
ctx->key, EVP_PKEY_RSA, 0) ||
|
||||||
|
!sk_prov_check_uint_param(params,
|
||||||
|
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||||
|
ctx->key, EVP_PKEY_RSA_PSS, 0)) {
|
||||||
|
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||||
|
"Implicit rejection is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default_set_params_fn = (OSSL_FUNC_asym_cipher_set_ctx_params_fn *)
|
default_set_params_fn = (OSSL_FUNC_asym_cipher_set_ctx_params_fn *)
|
||||||
sk_prov_get_default_asym_func(ctx->provctx,
|
sk_prov_get_default_asym_func(ctx->provctx,
|
||||||
ctx->type,
|
ctx->type,
|
||||||
@@ -1125,6 +1181,14 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
|||||||
struct sk_prov_op_ctx *ctx = vctx;
|
struct sk_prov_op_ctx *ctx = vctx;
|
||||||
struct sk_prov_key *key = vkey;
|
struct sk_prov_key *key = vkey;
|
||||||
const OSSL_PARAM *p;
|
const OSSL_PARAM *p;
|
||||||
|
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||||
|
unsigned int implicit_rejection = 0;
|
||||||
|
OSSL_PARAM set_params[] = {
|
||||||
|
OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||||
|
&implicit_rejection),
|
||||||
|
OSSL_PARAM_END
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ctx == NULL || key == NULL)
|
if (ctx == NULL || key == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1133,6 +1197,20 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
|||||||
for (p = params; p != NULL && p->key != NULL; p++)
|
for (p = params; p != NULL && p->key != NULL; p++)
|
||||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||||
|
|
||||||
|
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||||
|
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
|
||||||
|
if (!sk_prov_check_uint_param(params,
|
||||||
|
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||||
|
key, EVP_PKEY_RSA, 0) ||
|
||||||
|
!sk_prov_check_uint_param(params,
|
||||||
|
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||||
|
key, EVP_PKEY_RSA_PSS, 0)) {
|
||||||
|
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||||
|
"Implicit rejection is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default_decrypt_init_fn = (OSSL_FUNC_asym_cipher_decrypt_init_fn *)
|
default_decrypt_init_fn = (OSSL_FUNC_asym_cipher_decrypt_init_fn *)
|
||||||
sk_prov_get_default_asym_func(ctx->provctx,
|
sk_prov_get_default_asym_func(ctx->provctx,
|
||||||
ctx->type,
|
ctx->type,
|
||||||
@@ -1155,6 +1233,26 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||||
|
if ((key->type == EVP_PKEY_RSA || key->type == EVP_PKEY_RSA_PSS) &&
|
||||||
|
key->secure_key != NULL) {
|
||||||
|
/*
|
||||||
|
* By default, implicit rejection is enabled for the default
|
||||||
|
* provider. We currently do not support implicit rejection with
|
||||||
|
* secure keys, so disable implicit rejection in the default
|
||||||
|
* provider operation context to report its status correctly
|
||||||
|
* with get-params.
|
||||||
|
*/
|
||||||
|
implicit_rejection = 0;
|
||||||
|
if (!sk_prov_asym_op_set_ctx_params(ctx, set_params)) {
|
||||||
|
sk_debug_op_ctx(ctx,
|
||||||
|
"ERROR: sk_prov_asym_op_set_ctx_params "
|
||||||
|
"failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1361,6 +1459,16 @@ static int sk_prov_sign_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|||||||
for (p = params; p != NULL && p->key != NULL; p++)
|
for (p = params; p != NULL && p->key != NULL; p++)
|
||||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||||
|
|
||||||
|
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||||
|
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||||
|
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||||
|
ctx->key, EVP_PKEY_EC, 0)) {
|
||||||
|
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||||
|
"Deterministic signature is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default_set_params_fn = (OSSL_FUNC_signature_set_ctx_params_fn *)
|
default_set_params_fn = (OSSL_FUNC_signature_set_ctx_params_fn *)
|
||||||
sk_prov_get_default_sign_func(ctx->provctx,
|
sk_prov_get_default_sign_func(ctx->provctx,
|
||||||
ctx->type, OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS);
|
ctx->type, OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS);
|
||||||
@@ -1701,6 +1809,11 @@ static int sk_prov_sign_op_get_pss_saltlen(struct sk_prov_op_ctx *ctx,
|
|||||||
salt_len = max_saltlen;
|
salt_len = max_saltlen;
|
||||||
else if (strcmp(saltlen, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
|
else if (strcmp(saltlen, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
|
||||||
salt_len = max_saltlen;
|
salt_len = max_saltlen;
|
||||||
|
#ifdef OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
|
||||||
|
else if (strcmp(saltlen,
|
||||||
|
OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
|
||||||
|
salt_len = MIN(max_saltlen, EVP_MD_size(mgf_md));
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
salt_len = atoi(saltlen);
|
salt_len = atoi(saltlen);
|
||||||
|
|
||||||
@@ -1729,6 +1842,16 @@ static int sk_prov_sign_op_sign_init(void *vctx, void *vkey,
|
|||||||
for (p = params; p != NULL && p->key != NULL; p++)
|
for (p = params; p != NULL && p->key != NULL; p++)
|
||||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||||
|
|
||||||
|
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||||
|
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||||
|
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||||
|
key, EVP_PKEY_EC, 0)) {
|
||||||
|
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||||
|
"Deterministic signature is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default_sign_init_fn = (OSSL_FUNC_signature_sign_init_fn *)
|
default_sign_init_fn = (OSSL_FUNC_signature_sign_init_fn *)
|
||||||
sk_prov_get_default_sign_func(ctx->provctx,
|
sk_prov_get_default_sign_func(ctx->provctx,
|
||||||
ctx->type,
|
ctx->type,
|
||||||
@@ -1955,6 +2078,16 @@ static int sk_prov_sign_op_digest_sign_init(struct sk_prov_op_ctx *ctx,
|
|||||||
for (p = params; p != NULL && p->key != NULL; p++)
|
for (p = params; p != NULL && p->key != NULL; p++)
|
||||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||||
|
|
||||||
|
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||||
|
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||||
|
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||||
|
key, EVP_PKEY_EC, 0)) {
|
||||||
|
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||||
|
"Deterministic signature is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default_digest_sign_init_fn =
|
default_digest_sign_init_fn =
|
||||||
(OSSL_FUNC_signature_digest_sign_init_fn *)
|
(OSSL_FUNC_signature_digest_sign_init_fn *)
|
||||||
sk_prov_get_default_sign_func(ctx->provctx,
|
sk_prov_get_default_sign_func(ctx->provctx,
|
||||||
@@ -2829,14 +2962,14 @@ static const OSSL_PARAM sk_prov_imexport_types[] = {
|
|||||||
OSSL_PARAM_END
|
OSSL_PARAM_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
static const OSSL_PARAM *sk_prov_keymgmt_export_types(
|
||||||
int pkey_type)
|
struct sk_prov_ctx *provctx,
|
||||||
|
int selection,
|
||||||
|
int pkey_type)
|
||||||
{
|
{
|
||||||
OSSL_FUNC_keymgmt_export_types_fn *default_export_types_fn;
|
OSSL_FUNC_keymgmt_export_types_fn *default_export_types_fn;
|
||||||
const OSSL_PARAM *default_parms = NULL, *params;
|
const OSSL_PARAM *default_parms = NULL, *params;
|
||||||
struct sk_prov_ctx *provctx;
|
|
||||||
|
|
||||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
|
||||||
if (provctx == NULL)
|
if (provctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -2864,14 +2997,14 @@ static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
|||||||
sk_prov_imexport_types);
|
sk_prov_imexport_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_import_types(int selection,
|
static const OSSL_PARAM *sk_prov_keymgmt_import_types(
|
||||||
int pkey_type)
|
struct sk_prov_ctx *provctx,
|
||||||
|
int selection,
|
||||||
|
int pkey_type)
|
||||||
{
|
{
|
||||||
OSSL_FUNC_keymgmt_import_types_fn *default_import_types_fn;
|
OSSL_FUNC_keymgmt_import_types_fn *default_import_types_fn;
|
||||||
const OSSL_PARAM *default_parms = NULL, *params;
|
const OSSL_PARAM *default_parms = NULL, *params;
|
||||||
struct sk_prov_ctx *provctx;
|
|
||||||
|
|
||||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
|
||||||
if (provctx == NULL)
|
if (provctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -3219,15 +3352,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_settable_params(void *vprovctx)
|
|||||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA);
|
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||||
|
}
|
||||||
|
#else
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *sk_prov_keymgmt_rsa_gen_init(void *vprovctx, int selection,
|
static void *sk_prov_keymgmt_rsa_gen_init(void *vprovctx, int selection,
|
||||||
const OSSL_PARAM params[])
|
const OSSL_PARAM params[])
|
||||||
@@ -3289,15 +3446,43 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_settable_params(void *vprovctx)
|
|||||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA_PSS);
|
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA_PSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||||
|
EVP_PKEY_RSA_PSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||||
|
EVP_PKEY_RSA_PSS);
|
||||||
|
}
|
||||||
|
#else
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA_PSS);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||||
|
EVP_PKEY_RSA_PSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA_PSS);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||||
|
EVP_PKEY_RSA_PSS);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *sk_prov_keymgmt_rsa_pss_gen_init(void *vprovctx, int selection,
|
static void *sk_prov_keymgmt_rsa_pss_gen_init(void *vprovctx, int selection,
|
||||||
const OSSL_PARAM params[])
|
const OSSL_PARAM params[])
|
||||||
@@ -3372,15 +3557,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_ec_settable_params(void *vprovctx)
|
|||||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_EC);
|
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_EC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types_ex(void *vprovctx,
|
||||||
|
int selection)
|
||||||
|
{
|
||||||
|
struct sk_prov_ctx *provctx = vprovctx;
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||||
|
}
|
||||||
|
#else
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_EC);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types(int selection)
|
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types(int selection)
|
||||||
{
|
{
|
||||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_EC);
|
struct sk_prov_ctx *provctx =
|
||||||
|
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||||
|
|
||||||
|
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *sk_prov_keymgmt_ec_gen_init(void *vprovctx, int selection,
|
static void *sk_prov_keymgmt_ec_gen_init(void *vprovctx, int selection,
|
||||||
const OSSL_PARAM params[])
|
const OSSL_PARAM params[])
|
||||||
@@ -4530,11 +4739,21 @@ static const OSSL_DISPATCH sk_prov_rsa_keymgmt_functions[] = {
|
|||||||
|
|
||||||
/* Import and export routines */
|
/* Import and export routines */
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_rsa_export_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_rsa_export_types },
|
(void (*)(void))sk_prov_keymgmt_rsa_export_types },
|
||||||
|
#endif
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_rsa_import_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_rsa_import_types },
|
(void (*)(void))sk_prov_keymgmt_rsa_import_types },
|
||||||
|
#endif
|
||||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||||
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
@@ -4579,11 +4798,21 @@ static const OSSL_DISPATCH sk_prov_rsapss_keymgmt_functions[] = {
|
|||||||
|
|
||||||
/* Import and export routines */
|
/* Import and export routines */
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types },
|
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types },
|
||||||
|
#endif
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types },
|
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types },
|
||||||
|
#endif
|
||||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||||
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
@@ -4628,11 +4857,21 @@ static const OSSL_DISPATCH sk_prov_ec_keymgmt_functions[] = {
|
|||||||
|
|
||||||
/* Import and export routines */
|
/* Import and export routines */
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_ec_export_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_ec_export_types },
|
(void (*)(void))sk_prov_keymgmt_ec_export_types },
|
||||||
|
#endif
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||||
|
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||||
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||||
|
(void (*)(void))sk_prov_keymgmt_ec_import_types_ex },
|
||||||
|
#else
|
||||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||||
(void (*)(void))sk_prov_keymgmt_ec_import_types },
|
(void (*)(void))sk_prov_keymgmt_ec_import_types },
|
||||||
|
#endif
|
||||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||||
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
|
|||||||
@@ -776,6 +776,10 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
|
|||||||
bn_s = NULL;
|
bn_s = NULL;
|
||||||
|
|
||||||
der_len = i2d_ECDSA_SIG(ec_sig, NULL);
|
der_len = i2d_ECDSA_SIG(ec_sig, NULL);
|
||||||
|
if (der_len <= 0) {
|
||||||
|
rc = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
*sig_len = der_len;
|
*sig_len = der_len;
|
||||||
@@ -788,13 +792,14 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
|
|||||||
|
|
||||||
memset(sig, 0, *sig_len);
|
memset(sig, 0, *sig_len);
|
||||||
der = sig;
|
der = sig;
|
||||||
*sig_len = i2d_ECDSA_SIG(ec_sig, &der);
|
der_len = i2d_ECDSA_SIG(ec_sig, &der);
|
||||||
|
if (der_len <= 0) {
|
||||||
if (*sig_len == 0) {
|
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*sig_len = der_len;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ec_sig != NULL)
|
if (ec_sig != NULL)
|
||||||
ECDSA_SIG_free(ec_sig);
|
ECDSA_SIG_free(ec_sig);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user