aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-07-17 00:41:43 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-05 01:41:43 -0400
commitbb593c0049fd6b6e420a6f68c5a688e14782dba1 (patch)
tree844f038aca08d97c89fb02b8b167f19fea2d141c /arch/powerpc/kernel
parentf18440fb7e4f95d2a8f882d3d27c8777101fac12 (diff)
powerpc/eeh: Aux PE data for error log
The patch allows PE (struct eeh_pe) instance to have auxillary data, whose size is configurable on basis of platform. For PowerNV, the auxillary data will be used to cache PHB diag-data for that PE (frozen PE or fenced PHB). In turn, we can retrieve the diag-data at any later points. It's useful for the case of VFIO PCI devices where the error log should be cached, and then be retrieved by the guest at later point. Also, it can avoid PHB diag-data overwritting if another frozen PE reported and the previous diag-data isn't fetched by guest. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/eeh_pe.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 77632abf6a75..00e3844525a6 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -32,9 +32,24 @@
32#include <asm/pci-bridge.h> 32#include <asm/pci-bridge.h>
33#include <asm/ppc-pci.h> 33#include <asm/ppc-pci.h>
34 34
35static int eeh_pe_aux_size = 0;
35static LIST_HEAD(eeh_phb_pe); 36static LIST_HEAD(eeh_phb_pe);
36 37
37/** 38/**
39 * eeh_set_pe_aux_size - Set PE auxillary data size
40 * @size: PE auxillary data size
41 *
42 * Set PE auxillary data size
43 */
44void eeh_set_pe_aux_size(int size)
45{
46 if (size < 0)
47 return;
48
49 eeh_pe_aux_size = size;
50}
51
52/**
38 * eeh_pe_alloc - Allocate PE 53 * eeh_pe_alloc - Allocate PE
39 * @phb: PCI controller 54 * @phb: PCI controller
40 * @type: PE type 55 * @type: PE type
@@ -44,9 +59,16 @@ static LIST_HEAD(eeh_phb_pe);
44static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type) 59static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
45{ 60{
46 struct eeh_pe *pe; 61 struct eeh_pe *pe;
62 size_t alloc_size;
63
64 alloc_size = sizeof(struct eeh_pe);
65 if (eeh_pe_aux_size) {
66 alloc_size = ALIGN(alloc_size, cache_line_size());
67 alloc_size += eeh_pe_aux_size;
68 }
47 69
48 /* Allocate PHB PE */ 70 /* Allocate PHB PE */
49 pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL); 71 pe = kzalloc(alloc_size, GFP_KERNEL);
50 if (!pe) return NULL; 72 if (!pe) return NULL;
51 73
52 /* Initialize PHB PE */ 74 /* Initialize PHB PE */
@@ -56,6 +78,8 @@ static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
56 INIT_LIST_HEAD(&pe->child); 78 INIT_LIST_HEAD(&pe->child);
57 INIT_LIST_HEAD(&pe->edevs); 79 INIT_LIST_HEAD(&pe->edevs);
58 80
81 pe->data = (void *)pe + ALIGN(sizeof(struct eeh_pe),
82 cache_line_size());
59 return pe; 83 return pe;
60} 84}
61 85