Skip to content

Commit c6202ca

Browse files
hikerockiesdavem330
authored andcommitted
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 <[email protected]> Cc: Khalid Aziz <[email protected]> Reviewed-by: Anthony Yznaga <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 94addb3 commit c6202ca

File tree

7 files changed

+168
-0
lines changed

7 files changed

+168
-0
lines changed

arch/sparc/include/asm/adi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

arch/sparc/include/asm/adi_64.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ([email protected])
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+
15+
struct adi_caps {
16+
__u64 blksz;
17+
__u64 nbits;
18+
__u64 ue_on_adi;
19+
};
20+
21+
struct adi_config {
22+
bool enabled;
23+
struct adi_caps caps;
24+
};
25+
26+
extern struct adi_config adi_state;
27+
28+
extern void mdesc_adi_init(void);
29+
30+
static inline bool adi_capable(void)
31+
{
32+
return adi_state.enabled;
33+
}
34+
35+
static inline unsigned long adi_blksize(void)
36+
{
37+
return adi_state.caps.blksz;
38+
}
39+
40+
static 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) */

arch/sparc/include/asm/elf_64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <asm/processor.h>
1111
#include <asm/extable_64.h>
1212
#include <asm/spitfire.h>
13+
#include <asm/adi.h>
1314

1415
/*
1516
* Sparc section types
@@ -215,9 +216,13 @@ extern unsigned int vdso_enabled;
215216

216217
#define ARCH_DLINFO \
217218
do { \
219+
extern struct adi_config adi_state; \
218220
if (vdso_enabled) \
219221
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
220222
(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); \
221226
} while (0)
222227

223228
struct linux_binprm;

arch/sparc/include/uapi/asm/auxvec.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33

44
#define AT_SYSINFO_EHDR 33
55

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
616
#define AT_VECTOR_SIZE_ARCH 1
17+
#endif
718

819
#endif /* !(__ASMSPARC_AUXVEC_H) */

arch/sparc/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ obj-$(CONFIG_SPARC64) += visemul.o
6969
obj-$(CONFIG_SPARC64) += hvapi.o
7070
obj-$(CONFIG_SPARC64) += sstate.o
7171
obj-$(CONFIG_SPARC64) += mdesc.o
72+
obj-$(CONFIG_SPARC64) += adi_64.o
7273
obj-$(CONFIG_SPARC64) += pcr.o
7374
obj-$(CONFIG_SPARC64) += nmi.o
7475
obj-$(CONFIG_SPARC64_SMP) += cpumap.o

arch/sparc/kernel/adi_64.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ([email protected])
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+
14+
struct 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+
*/
25+
void __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+
90+
adi_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+
}

arch/sparc/kernel/mdesc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/uaccess.h>
2323
#include <asm/oplib.h>
2424
#include <asm/smp.h>
25+
#include <asm/adi.h>
2526

2627
/* Unlike the OBP device tree, the machine description is a full-on
2728
* DAG. An arbitrary number of ARCs are possible from one
@@ -1345,5 +1346,6 @@ void __init sun4v_mdesc_init(void)
13451346

13461347
cur_mdesc = hp;
13471348

1349+
mdesc_adi_init();
13481350
report_platform_properties();
13491351
}

0 commit comments

Comments
 (0)