Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
fd086195
Commit
fd086195
authored
Dec 21, 2017
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back APEI material for v4.16.
parents
bb82e0b4
24bc8f03
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
33 deletions
+46
-33
drivers/acpi/apei/ghes.c
drivers/acpi/apei/ghes.c
+46
-33
No files found.
drivers/acpi/apei/ghes.c
View file @
fd086195
...
...
@@ -414,6 +414,51 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
#endif
}
/*
* PCIe AER errors need to be sent to the AER driver for reporting and
* recovery. The GHES severities map to the following AER severities and
* require the following handling:
*
* GHES_SEV_CORRECTABLE -> AER_CORRECTABLE
* These need to be reported by the AER driver but no recovery is
* necessary.
* GHES_SEV_RECOVERABLE -> AER_NONFATAL
* GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL
* These both need to be reported and recovered from by the AER driver.
* GHES_SEV_PANIC does not make it to this handling since the kernel must
* panic.
*/
static
void
ghes_handle_aer
(
struct
acpi_hest_generic_data
*
gdata
)
{
#ifdef CONFIG_ACPI_APEI_PCIEAER
struct
cper_sec_pcie
*
pcie_err
=
acpi_hest_get_payload
(
gdata
);
if
(
pcie_err
->
validation_bits
&
CPER_PCIE_VALID_DEVICE_ID
&&
pcie_err
->
validation_bits
&
CPER_PCIE_VALID_AER_INFO
)
{
unsigned
int
devfn
;
int
aer_severity
;
devfn
=
PCI_DEVFN
(
pcie_err
->
device_id
.
device
,
pcie_err
->
device_id
.
function
);
aer_severity
=
cper_severity_to_aer
(
gdata
->
error_severity
);
/*
* If firmware reset the component to contain
* the error, we must reinitialize it before
* use, so treat it as a fatal AER error.
*/
if
(
gdata
->
flags
&
CPER_SEC_RESET
)
aer_severity
=
AER_FATAL
;
aer_recover_queue
(
pcie_err
->
device_id
.
segment
,
pcie_err
->
device_id
.
bus
,
devfn
,
aer_severity
,
(
struct
aer_capability_regs
*
)
pcie_err
->
aer_info
);
}
#endif
}
static
void
ghes_do_proc
(
struct
ghes
*
ghes
,
const
struct
acpi_hest_generic_status
*
estatus
)
{
...
...
@@ -441,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes,
arch_apei_report_mem_error
(
sev
,
mem_err
);
ghes_handle_memory_failure
(
gdata
,
sev
);
}
#ifdef CONFIG_ACPI_APEI_PCIEAER
else
if
(
guid_equal
(
sec_type
,
&
CPER_SEC_PCIE
))
{
struct
cper_sec_pcie
*
pcie_err
=
acpi_hest_get_payload
(
gdata
);
if
(
sev
==
GHES_SEV_RECOVERABLE
&&
sec_sev
==
GHES_SEV_RECOVERABLE
&&
pcie_err
->
validation_bits
&
CPER_PCIE_VALID_DEVICE_ID
&&
pcie_err
->
validation_bits
&
CPER_PCIE_VALID_AER_INFO
)
{
unsigned
int
devfn
;
int
aer_severity
;
devfn
=
PCI_DEVFN
(
pcie_err
->
device_id
.
device
,
pcie_err
->
device_id
.
function
);
aer_severity
=
cper_severity_to_aer
(
gdata
->
error_severity
);
/*
* If firmware reset the component to contain
* the error, we must reinitialize it before
* use, so treat it as a fatal AER error.
*/
if
(
gdata
->
flags
&
CPER_SEC_RESET
)
aer_severity
=
AER_FATAL
;
aer_recover_queue
(
pcie_err
->
device_id
.
segment
,
pcie_err
->
device_id
.
bus
,
devfn
,
aer_severity
,
(
struct
aer_capability_regs
*
)
pcie_err
->
aer_info
);
}
ghes_handle_aer
(
gdata
);
}
#endif
else
if
(
guid_equal
(
sec_type
,
&
CPER_SEC_PROC_ARM
))
{
struct
cper_sec_proc_arm
*
err
=
acpi_hest_get_payload
(
gdata
);
...
...
@@ -870,7 +886,6 @@ static void ghes_print_queued_estatus(void)
struct
ghes_estatus_node
*
estatus_node
;
struct
acpi_hest_generic
*
generic
;
struct
acpi_hest_generic_status
*
estatus
;
u32
len
,
node_len
;
llnode
=
llist_del_all
(
&
ghes_estatus_llist
);
/*
...
...
@@ -882,8 +897,6 @@ static void ghes_print_queued_estatus(void)
estatus_node
=
llist_entry
(
llnode
,
struct
ghes_estatus_node
,
llnode
);
estatus
=
GHES_ESTATUS_FROM_NODE
(
estatus_node
);
len
=
cper_estatus_len
(
estatus
);
node_len
=
GHES_ESTATUS_NODE_LEN
(
len
);
generic
=
estatus_node
->
generic
;
ghes_print_estatus
(
NULL
,
generic
,
estatus
);
llnode
=
llnode
->
next
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment