summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhalid Aziz <khalid.aziz@oracle.com>2018-02-21 12:15:48 -0500
committerDavid S. Miller <davem@davemloft.net>2018-03-18 10:38:46 -0400
commitc6202ca764ac7b3728e29bca616567beb57fbac7 (patch)
tree70c5121ba4dc4d6756fac91ef3c7857da1edd314
parent94addb3530bb81e7ffde2c5c50a88310f734c365 (diff)
sparc64: Add auxiliary vectors to report platform ADI properties
ADI feature on M7 and newer processors has three important properties relevant to userspace apps using ADI capabilities - (1) Size of block of memory an ADI version tag applies to, (2) Number of uppermost bits in virtual address used to encode ADI tag, and (3) The value M7 processor will force the ADI tags to if it detects uncorrectable error in an ADI tagged cacheline. Kernel can retrieve these properties for a platform through machine description provided by the firmware. This patch adds code to retrieve these properties and report them to userspace through auxiliary vectors. Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com> Cc: Khalid Aziz <khalid@gonehiking.org> Reviewed-by: Anthony Yznaga <anthony.yznaga@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/include/asm/adi.h6
-rw-r--r--arch/sparc/include/asm/adi_64.h47
-rw-r--r--arch/sparc/include/asm/elf_64.h5
-rw-r--r--arch/sparc/include/uapi/asm/auxvec.h11
-rw-r--r--arch/sparc/kernel/Makefile1
-rw-r--r--arch/sparc/kernel/adi_64.c96
-rw-r--r--arch/sparc/kernel/mdesc.c2
7 files changed, 168 insertions, 0 deletions
diff --git a/arch/sparc/include/asm/adi.h b/arch/sparc/include/asm/adi.h
new file mode 100644
index 000000000000..acad0d04e4c6
--- /dev/null
+++ b/arch/sparc/include/asm/adi.h
@@ -0,0 +1,6 @@
1#ifndef ___ASM_SPARC_ADI_H
2#define ___ASM_SPARC_ADI_H
3#if defined(__sparc__) && defined(__arch64__)
4#include <asm/adi_64.h>
5#endif
6#endif
diff --git a/arch/sparc/include/asm/adi_64.h b/arch/sparc/include/asm/adi_64.h
new file mode 100644
index 000000000000..85f7a763af85
--- /dev/null
+++ b/arch/sparc/include/asm/adi_64.h
@@ -0,0 +1,47 @@
1/* adi_64.h: ADI related data structures
2 *
3 * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
4 * Author: Khalid Aziz (khalid.aziz@oracle.com)
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8#ifndef __ASM_SPARC64_ADI_H
9#define __ASM_SPARC64_ADI_H
10
11#include <linux/types.h>
12
13#ifndef __ASSEMBLY__
14
15struct adi_caps {
16 __u64 blksz;
17 __u64 nbits;
18 __u64 ue_on_adi;
19};
20
21struct adi_config {
22 bool enabled;
23 struct adi_caps caps;
24};
25
26extern struct adi_config adi_state;
27
28extern void mdesc_adi_init(void);
29
30static inline bool adi_capable(void)
31{
32 return adi_state.enabled;
33}
34
35static inline unsigned long adi_blksize(void)
36{
37 return adi_state.caps.blksz;
38}
39
40static inline unsigned long adi_nbits(void)
41{
42 return adi_state.caps.nbits;
43}
44
45#endif /* __ASSEMBLY__ */
46
47#endif /* !(__ASM_SPARC64_ADI_H) */
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index 25340df3570c..7e078bc73ef5 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -10,6 +10,7 @@
10#include <asm/processor.h> 10#include <asm/processor.h>
11#include <asm/extable_64.h> 11#include <asm/extable_64.h>
12#include <asm/spitfire.h> 12#include <asm/spitfire.h>
13#include <asm/adi.h>
13 14
14/* 15/*
15 * Sparc section types 16 * Sparc section types
@@ -215,9 +216,13 @@ extern unsigned int vdso_enabled;
215 216
216#define ARCH_DLINFO \ 217#define ARCH_DLINFO \
217do { \ 218do { \
219 extern struct adi_config adi_state; \
218 if (vdso_enabled) \ 220 if (vdso_enabled) \
219 NEW_AUX_ENT(AT_SYSINFO_EHDR, \ 221 NEW_AUX_ENT(AT_SYSINFO_EHDR, \
220 (unsigned long)current->mm->context.vdso); \ 222 (unsigned long)current->mm->context.vdso); \
223 NEW_AUX_ENT(AT_ADI_BLKSZ, adi_state.caps.blksz); \
224 NEW_AUX_ENT(AT_ADI_NBITS, adi_state.caps.nbits); \
225 NEW_AUX_ENT(AT_ADI_UEONADI, adi_state.caps.ue_on_adi); \
221} while (0) 226} while (0)
222 227
223struct linux_binprm; 228struct linux_binprm;
diff --git a/arch/sparc/include/uapi/asm/auxvec.h b/arch/sparc/include/uapi/asm/auxvec.h
index 5f80a70cc901..f9937ccfcd99 100644
--- a/arch/sparc/include/uapi/asm/auxvec.h
+++ b/arch/sparc/include/uapi/asm/auxvec.h
@@ -3,6 +3,17 @@
3 3
4#define AT_SYSINFO_EHDR 33 4#define AT_SYSINFO_EHDR 33
5 5
6#ifdef CONFIG_SPARC64
7/* Avoid overlap with other AT_* values since they are consolidated in
8 * glibc and any overlaps can cause problems
9 */
10#define AT_ADI_BLKSZ 48
11#define AT_ADI_NBITS 49
12#define AT_ADI_UEONADI 50
13
14#define AT_VECTOR_SIZE_ARCH 4
15#else
6#define AT_VECTOR_SIZE_ARCH 1 16#define AT_VECTOR_SIZE_ARCH 1
17#endif
7 18
8#endif /* !(__ASMSPARC_AUXVEC_H) */ 19#endif /* !(__ASMSPARC_AUXVEC_H) */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index cc97545737f0..76cb57750dda 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_SPARC64) += visemul.o
69obj-$(CONFIG_SPARC64) += hvapi.o 69obj-$(CONFIG_SPARC64) += hvapi.o
70obj-$(CONFIG_SPARC64) += sstate.o 70obj-$(CONFIG_SPARC64) += sstate.o
71obj-$(CONFIG_SPARC64) += mdesc.o 71obj-$(CONFIG_SPARC64) += mdesc.o
72obj-$(CONFIG_SPARC64) += adi_64.o
72obj-$(CONFIG_SPARC64) += pcr.o 73obj-$(CONFIG_SPARC64) += pcr.o
73obj-$(CONFIG_SPARC64) += nmi.o 74obj-$(CONFIG_SPARC64) += nmi.o
74obj-$(CONFIG_SPARC64_SMP) += cpumap.o 75obj-$(CONFIG_SPARC64_SMP) += cpumap.o
diff --git a/arch/sparc/kernel/adi_64.c b/arch/sparc/kernel/adi_64.c
new file mode 100644
index 000000000000..8fb72585d9f1
--- /dev/null
+++ b/arch/sparc/kernel/adi_64.c
@@ -0,0 +1,96 @@
1/* adi_64.c: support for ADI (Application Data Integrity) feature on
2 * sparc m7 and newer processors. This feature is also known as
3 * SSM (Silicon Secured Memory).
4 *
5 * Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved.
6 * Author: Khalid Aziz (khalid.aziz@oracle.com)
7 *
8 * This work is licensed under the terms of the GNU GPL, version 2.
9 */
10#include <linux/init.h>
11#include <asm/mdesc.h>
12#include <asm/adi_64.h>
13
14struct adi_config adi_state;
15
16/* mdesc_adi_init() : Parse machine description provided by the
17 * hypervisor to detect ADI capabilities
18 *
19 * Hypervisor reports ADI capabilities of platform in "hwcap-list" property
20 * for "cpu" node. If the platform supports ADI, "hwcap-list" property
21 * contains the keyword "adp". If the platform supports ADI, "platform"
22 * node will contain "adp-blksz", "adp-nbits" and "ue-on-adp" properties
23 * to describe the ADI capabilities.
24 */
25void __init mdesc_adi_init(void)
26{
27 struct mdesc_handle *hp = mdesc_grab();
28 const char *prop;
29 u64 pn, *val;
30 int len;
31
32 if (!hp)
33 goto adi_not_found;
34
35 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu");
36 if (pn == MDESC_NODE_NULL)
37 goto adi_not_found;
38
39 prop = mdesc_get_property(hp, pn, "hwcap-list", &len);
40 if (!prop)
41 goto adi_not_found;
42
43 /*
44 * Look for "adp" keyword in hwcap-list which would indicate
45 * ADI support
46 */
47 adi_state.enabled = false;
48 while (len) {
49 int plen;
50
51 if (!strcmp(prop, "adp")) {
52 adi_state.enabled = true;
53 break;
54 }
55
56 plen = strlen(prop) + 1;
57 prop += plen;
58 len -= plen;
59 }
60
61 if (!adi_state.enabled)
62 goto adi_not_found;
63
64 /* Find the ADI properties in "platform" node. If all ADI
65 * properties are not found, ADI support is incomplete and
66 * do not enable ADI in the kernel.
67 */
68 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform");
69 if (pn == MDESC_NODE_NULL)
70 goto adi_not_found;
71
72 val = (u64 *) mdesc_get_property(hp, pn, "adp-blksz", &len);
73 if (!val)
74 goto adi_not_found;
75 adi_state.caps.blksz = *val;
76
77 val = (u64 *) mdesc_get_property(hp, pn, "adp-nbits", &len);
78 if (!val)
79 goto adi_not_found;
80 adi_state.caps.nbits = *val;
81
82 val = (u64 *) mdesc_get_property(hp, pn, "ue-on-adp", &len);
83 if (!val)
84 goto adi_not_found;
85 adi_state.caps.ue_on_adi = *val;
86
87 mdesc_release(hp);
88 return;
89
90adi_not_found:
91 adi_state.enabled = false;
92 adi_state.caps.blksz = 0;
93 adi_state.caps.nbits = 0;
94 if (hp)
95 mdesc_release(hp);
96}
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 418592a09b41..39a2503fa3e1 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -22,6 +22,7 @@
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <asm/oplib.h> 23#include <asm/oplib.h>
24#include <asm/smp.h> 24#include <asm/smp.h>
25#include <asm/adi.h>
25 26
26/* Unlike the OBP device tree, the machine description is a full-on 27/* Unlike the OBP device tree, the machine description is a full-on
27 * DAG. An arbitrary number of ARCs are possible from one 28 * DAG. An arbitrary number of ARCs are possible from one
@@ -1345,5 +1346,6 @@ void __init sun4v_mdesc_init(void)
1345 1346
1346 cur_mdesc = hp; 1347 cur_mdesc = hp;
1347 1348
1349 mdesc_adi_init();
1348 report_platform_properties(); 1350 report_platform_properties();
1349} 1351}