51
51
#include <acpi/actbl1.h>
52
52
#include <acpi/ghes.h>
53
53
#include <acpi/apei.h>
54
+ #include <asm/fixmap.h>
54
55
#include <asm/tlbflush.h>
55
56
#include <ras/ras_event.h>
56
57
@@ -112,7 +113,7 @@ static DEFINE_MUTEX(ghes_list_mutex);
112
113
* Because the memory area used to transfer hardware error information
113
114
* from BIOS to Linux can be determined only in NMI, IRQ or timer
114
115
* handler, but general ioremap can not be used in atomic context, so
115
- * a special version of atomic ioremap is implemented for that .
116
+ * the fixmap is used instead .
116
117
*/
117
118
118
119
/*
@@ -126,8 +127,8 @@ static DEFINE_MUTEX(ghes_list_mutex);
126
127
/* virtual memory area for atomic ioremap */
127
128
static struct vm_struct * ghes_ioremap_area ;
128
129
/*
129
- * These 2 spinlock is used to prevent atomic ioremap virtual memory
130
- * area from being mapped simultaneously.
130
+ * These 2 spinlocks are used to prevent the fixmap entries from being used
131
+ * simultaneously.
131
132
*/
132
133
static DEFINE_RAW_SPINLOCK (ghes_ioremap_lock_nmi );
133
134
static DEFINE_SPINLOCK (ghes_ioremap_lock_irq );
@@ -159,52 +160,36 @@ static void ghes_ioremap_exit(void)
159
160
160
161
static void __iomem * ghes_ioremap_pfn_nmi (u64 pfn )
161
162
{
162
- unsigned long vaddr ;
163
163
phys_addr_t paddr ;
164
164
pgprot_t prot ;
165
165
166
- vaddr = (unsigned long )GHES_IOREMAP_NMI_PAGE (ghes_ioremap_area -> addr );
167
-
168
166
paddr = pfn << PAGE_SHIFT ;
169
167
prot = arch_apei_get_mem_attribute (paddr );
170
- ioremap_page_range ( vaddr , vaddr + PAGE_SIZE , paddr , prot );
168
+ __set_fixmap ( FIX_APEI_GHES_NMI , paddr , prot );
171
169
172
- return (void __iomem * )vaddr ;
170
+ return (void __iomem * ) fix_to_virt ( FIX_APEI_GHES_NMI ) ;
173
171
}
174
172
175
173
static void __iomem * ghes_ioremap_pfn_irq (u64 pfn )
176
174
{
177
- unsigned long vaddr , paddr ;
175
+ phys_addr_t paddr ;
178
176
pgprot_t prot ;
179
177
180
- vaddr = (unsigned long )GHES_IOREMAP_IRQ_PAGE (ghes_ioremap_area -> addr );
181
-
182
178
paddr = pfn << PAGE_SHIFT ;
183
179
prot = arch_apei_get_mem_attribute (paddr );
180
+ __set_fixmap (FIX_APEI_GHES_IRQ , paddr , prot );
184
181
185
- ioremap_page_range (vaddr , vaddr + PAGE_SIZE , paddr , prot );
186
-
187
- return (void __iomem * )vaddr ;
182
+ return (void __iomem * ) fix_to_virt (FIX_APEI_GHES_IRQ );
188
183
}
189
184
190
- static void ghes_iounmap_nmi (void __iomem * vaddr_ptr )
185
+ static void ghes_iounmap_nmi (void )
191
186
{
192
- unsigned long vaddr = (unsigned long __force )vaddr_ptr ;
193
- void * base = ghes_ioremap_area -> addr ;
194
-
195
- BUG_ON (vaddr != (unsigned long )GHES_IOREMAP_NMI_PAGE (base ));
196
- unmap_kernel_range_noflush (vaddr , PAGE_SIZE );
197
- arch_apei_flush_tlb_one (vaddr );
187
+ clear_fixmap (FIX_APEI_GHES_NMI );
198
188
}
199
189
200
- static void ghes_iounmap_irq (void __iomem * vaddr_ptr )
190
+ static void ghes_iounmap_irq (void )
201
191
{
202
- unsigned long vaddr = (unsigned long __force )vaddr_ptr ;
203
- void * base = ghes_ioremap_area -> addr ;
204
-
205
- BUG_ON (vaddr != (unsigned long )GHES_IOREMAP_IRQ_PAGE (base ));
206
- unmap_kernel_range_noflush (vaddr , PAGE_SIZE );
207
- arch_apei_flush_tlb_one (vaddr );
192
+ clear_fixmap (FIX_APEI_GHES_IRQ );
208
193
}
209
194
210
195
static int ghes_estatus_pool_init (void )
@@ -360,10 +345,10 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len,
360
345
paddr += trunk ;
361
346
buffer += trunk ;
362
347
if (in_nmi ) {
363
- ghes_iounmap_nmi (vaddr );
348
+ ghes_iounmap_nmi ();
364
349
raw_spin_unlock (& ghes_ioremap_lock_nmi );
365
350
} else {
366
- ghes_iounmap_irq (vaddr );
351
+ ghes_iounmap_irq ();
367
352
spin_unlock_irqrestore (& ghes_ioremap_lock_irq , flags );
368
353
}
369
354
}
@@ -851,17 +836,8 @@ static void ghes_sea_remove(struct ghes *ghes)
851
836
synchronize_rcu ();
852
837
}
853
838
#else /* CONFIG_ACPI_APEI_SEA */
854
- static inline void ghes_sea_add (struct ghes * ghes )
855
- {
856
- pr_err (GHES_PFX "ID: %d, trying to add SEA notification which is not supported\n" ,
857
- ghes -> generic -> header .source_id );
858
- }
859
-
860
- static inline void ghes_sea_remove (struct ghes * ghes )
861
- {
862
- pr_err (GHES_PFX "ID: %d, trying to remove SEA notification which is not supported\n" ,
863
- ghes -> generic -> header .source_id );
864
- }
839
+ static inline void ghes_sea_add (struct ghes * ghes ) { }
840
+ static inline void ghes_sea_remove (struct ghes * ghes ) { }
865
841
#endif /* CONFIG_ACPI_APEI_SEA */
866
842
867
843
#ifdef CONFIG_HAVE_ACPI_APEI_NMI
@@ -1063,23 +1039,9 @@ static void ghes_nmi_init_cxt(void)
1063
1039
init_irq_work (& ghes_proc_irq_work , ghes_proc_in_irq );
1064
1040
}
1065
1041
#else /* CONFIG_HAVE_ACPI_APEI_NMI */
1066
- static inline void ghes_nmi_add (struct ghes * ghes )
1067
- {
1068
- pr_err (GHES_PFX "ID: %d, trying to add NMI notification which is not supported!\n" ,
1069
- ghes -> generic -> header .source_id );
1070
- BUG ();
1071
- }
1072
-
1073
- static inline void ghes_nmi_remove (struct ghes * ghes )
1074
- {
1075
- pr_err (GHES_PFX "ID: %d, trying to remove NMI notification which is not supported!\n" ,
1076
- ghes -> generic -> header .source_id );
1077
- BUG ();
1078
- }
1079
-
1080
- static inline void ghes_nmi_init_cxt (void )
1081
- {
1082
- }
1042
+ static inline void ghes_nmi_add (struct ghes * ghes ) { }
1043
+ static inline void ghes_nmi_remove (struct ghes * ghes ) { }
1044
+ static inline void ghes_nmi_init_cxt (void ) { }
1083
1045
#endif /* CONFIG_HAVE_ACPI_APEI_NMI */
1084
1046
1085
1047
static int ghes_probe (struct platform_device * ghes_dev )
0 commit comments