From: venkatesh.pallipadi@intel.com
To: ak@muc.de, ebiederm@xmission.com, rdreier@cisco.com,
torvalds@linux-foundation.org, gregkh@suse.de, airlied@skynet.ie,
davej@redhat.com, mingo@elte.hu, tglx@linutronix.de,
hpa@zytor.com, akpm@linux-foundation.org, arjan@infradead.org,
jesse.barnes@intel.com, davem@davemloft.net
Cc: linux-kernel@vger.kernel.org,
Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>,
Suresh Siddha <suresh.b.siddha@intel.com>
Subject: [patch 01/11] PAT x86: Make acpi/other drivers map memory instead of assuming identity map
Date: Thu, 10 Jan 2008 10:48:41 -0800 [thread overview]
Message-ID: <20080110184854.557190000@intel.com> (raw)
In-Reply-To: 20080110184840.927409000@intel.com
[-- Attachment #1: map_instead_of_va.patch --]
[-- Type: text/plain, Size: 14407 bytes --]
This series is heavily derived from the PAT patchset by Eric Biederman and
Andi Kleen.
http://www.firstfloor.org/pub/ak/x86_64/pat/
This patchset is a followup of "PAT support for X86_64"
http://www.ussg.iu.edu/hypermail/linux/kernel/0712.1/2268.html
Things changed from the above (Dec 13 2007) version:
* PAT mappings now used are - (0,WB) (1,WT) (2,WC) (3,UC).
* Covers both i386 and x86_64.
* Resolve the /sysfs issue by exporting wc and uc interfaces.
* Piggyback PAT initialization on existing MTRR initialization as they
have same setup rules.
* Avoid early table allocation problem for x86_64 by doing the reserved
region pruning later in the boot. Handle both memory identity mapping and
kernel test mapping.
* Handle fork() and /dev/mem mapping and unmapping cases.
This patch:
Some boot code has assumptions about entire memory being mapped in identity
mapping. Fix them to use some form of mapping instead. Places fixed below:
* Generic __acpi_map_table
* Looking for RSD PTR at boot time
* Looking for mp table
* get_bios_ebda and ebda size
* pci-calgary (Compile tested only. Will be great if someone who has this
hardware can verify that this change works fine)
(This patch is testable as a standalone patch)
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
Patchset is against Ingo's x86 branch from 2 days ago. Will need some merging
effort with Andi's CPA changes and few other changes like pgtable.h unification.
Index: linux-2.6.git/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/acpi/boot.c 2008-01-08 03:31:31.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/acpi/boot.c 2008-01-08 03:43:46.000000000 -0800
@@ -105,16 +105,20 @@
#ifdef CONFIG_X86_64
-/* rely on all ACPI tables being in the direct mapping */
char *__acpi_map_table(unsigned long phys_addr, unsigned long size)
{
if (!phys_addr || !size)
return NULL;
- if (phys_addr+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE)
- return __va(phys_addr);
+ return early_ioremap(phys_addr, size);
+}
- return NULL;
+void __acpi_unmap_table(void * addr, unsigned long size)
+{
+ if (!addr || !size)
+ return;
+
+ early_iounmap(addr, size);
}
#else
@@ -158,6 +162,11 @@
return ((unsigned char *)base + offset);
}
+
+void __acpi_unmap_table(void * addr, unsigned long size)
+{
+}
+
#endif
#ifdef CONFIG_PCI_MMCONFIG
@@ -586,17 +595,23 @@
{
unsigned long offset = 0;
unsigned long sig_len = sizeof("RSD PTR ") - 1;
+ char * virt_addr;
+ virt_addr = __acpi_map_table(start, length);
+ if (!virt_addr)
+ return 0;
/*
* Scan all 16-byte boundaries of the physical memory region for the
* RSDP signature.
*/
for (offset = 0; offset < length; offset += 16) {
- if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
+ if (strncmp(virt_addr + offset, "RSD PTR ", sig_len))
continue;
+ __acpi_unmap_table(virt_addr, length);
return (start + offset);
}
+ __acpi_unmap_table(virt_addr, length);
return 0;
}
Index: linux-2.6.git/drivers/acpi/osl.c
===================================================================
--- linux-2.6.git.orig/drivers/acpi/osl.c 2008-01-08 03:31:31.000000000 -0800
+++ linux-2.6.git/drivers/acpi/osl.c 2008-01-08 03:43:46.000000000 -0800
@@ -231,6 +231,8 @@
{
if (acpi_gbl_permanent_mmap) {
iounmap(virt);
+ } else {
+ __acpi_unmap_table(virt, size);
}
}
EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
Index: linux-2.6.git/include/linux/acpi.h
===================================================================
--- linux-2.6.git.orig/include/linux/acpi.h 2008-01-08 03:31:38.000000000 -0800
+++ linux-2.6.git/include/linux/acpi.h 2008-01-08 03:43:46.000000000 -0800
@@ -79,6 +79,7 @@
typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
+void __acpi_unmap_table (void * addr, unsigned long size);
unsigned long acpi_find_rsdp (void);
int acpi_boot_init (void);
int acpi_boot_table_init (void);
Index: linux-2.6.git/arch/x86/kernel/mpparse_64.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/mpparse_64.c 2008-01-08 03:31:31.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/mpparse_64.c 2008-01-08 03:43:46.000000000 -0800
@@ -29,6 +29,7 @@
#include <asm/io_apic.h>
#include <asm/proto.h>
#include <asm/acpi.h>
+#include <asm/bios_ebda.h>
/* Have we found an MP table */
int smp_found_config;
@@ -535,9 +536,12 @@
static int __init smp_scan_config (unsigned long base, unsigned long length)
{
extern void __bad_mpf_size(void);
- unsigned int *bp = phys_to_virt(base);
+ unsigned int *bp = (unsigned int *)__acpi_map_table(base, length);
struct intel_mp_floating *mpf;
+ if (!bp)
+ return 0;
+
Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
if (sizeof(*mpf) != 16)
__bad_mpf_size();
@@ -555,11 +559,13 @@
if (mpf->mpf_physptr)
reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE);
mpf_found = mpf;
+ __acpi_unmap_table((char *)bp, length);
return 1;
}
bp += 4;
length -= 16;
}
+ __acpi_unmap_table((char *)bp, length);
return 0;
}
@@ -592,11 +598,11 @@
* should be fixed.
*/
- address = *(unsigned short *)phys_to_virt(0x40E);
- address <<= 4;
- if (smp_scan_config(address, 0x1000))
+ address = get_bios_ebda();
+ if (address && smp_scan_config(address, 0x1000))
return;
+
/* If we have come this far, we did not find an MP table */
printk(KERN_INFO "No mptable found.\n");
}
Index: linux-2.6.git/arch/x86/mm/init_64.c
===================================================================
--- linux-2.6.git.orig/arch/x86/mm/init_64.c 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/arch/x86/mm/init_64.c 2008-01-08 03:43:46.000000000 -0800
@@ -208,7 +208,7 @@
}
/* Must run before zap_low_mappings */
-__meminit void *early_ioremap(unsigned long addr, unsigned long size)
+void *early_ioremap(unsigned long addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd, *last_pmd;
@@ -237,7 +237,7 @@
}
/* To avoid virtual aliases later */
-__meminit void early_iounmap(void *addr, unsigned long size)
+void early_iounmap(void *addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd;
Index: linux-2.6.git/include/asm-x86/rio.h
===================================================================
--- linux-2.6.git.orig/include/asm-x86/rio.h 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/include/asm-x86/rio.h 2008-01-08 03:43:46.000000000 -0800
@@ -8,6 +8,8 @@
#ifndef __ASM_RIO_H
#define __ASM_RIO_H
+#include <asm/bios_ebda.h>
+
#define RIO_TABLE_VERSION 3
struct rio_table_hdr {
@@ -60,15 +62,4 @@
ALT_CALGARY = 5, /* Second Planar Calgary */
};
-/*
- * there is a real-mode segmented pointer pointing to the
- * 4K EBDA area at 0x40E.
- */
-static inline unsigned long get_bios_ebda(void)
-{
- unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL);
- address <<= 4;
- return address;
-}
-
#endif /* __ASM_RIO_H */
Index: linux-2.6.git/arch/x86/kernel/mpparse_32.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/mpparse_32.c 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/mpparse_32.c 2008-01-08 03:43:46.000000000 -0800
@@ -27,11 +27,11 @@
#include <asm/mtrr.h>
#include <asm/mpspec.h>
#include <asm/io_apic.h>
+#include <asm/bios_ebda.h>
#include <mach_apic.h>
#include <mach_apicdef.h>
#include <mach_mpparse.h>
-#include <bios_ebda.h>
/* Have we found an MP table */
int smp_found_config;
@@ -718,9 +718,12 @@
static int __init smp_scan_config (unsigned long base, unsigned long length)
{
- unsigned long *bp = phys_to_virt(base);
+ unsigned long *bp = (unsigned long *)__acpi_map_table(base, length);
struct intel_mp_floating *mpf;
+ if (!bp)
+ return 0;
+
Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
if (sizeof(*mpf) != 16)
printk("Error: MPF size\n");
@@ -755,11 +758,13 @@
}
mpf_found = mpf;
+ __acpi_unmap_table((char *)bp, length);
return 1;
}
bp += 4;
length -= 16;
}
+ __acpi_unmap_table((char *)bp, length);
return 0;
}
Index: linux-2.6.git/arch/x86/kernel/pci-calgary_64.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/pci-calgary_64.c 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/pci-calgary_64.c 2008-01-08 03:43:46.000000000 -0800
@@ -1180,6 +1180,7 @@
}
}
+ early_iounmap((void *)rio_table_hdr, sizeof(struct rio_table_hdr));
return 0;
error:
@@ -1188,6 +1189,7 @@
if (bus_info[bus].bbar)
iounmap(bus_info[bus].bbar);
+ early_iounmap((void *)rio_table_hdr, sizeof(struct rio_table_hdr));
return ret;
}
@@ -1337,7 +1339,8 @@
int bus;
void *tbl;
int calgary_found = 0;
- unsigned long ptr;
+ unsigned long addr;
+ unsigned short *ptr;
unsigned int offset, prev_offset;
int ret;
@@ -1356,7 +1359,9 @@
printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
- ptr = (unsigned long)phys_to_virt(get_bios_ebda());
+ addr = get_bios_ebda();
+ if (!addr)
+ return;
rio_table_hdr = NULL;
prev_offset = 0;
@@ -1366,14 +1371,22 @@
* Only parse up until the offset increases:
*/
while (offset > prev_offset) {
+ ptr = early_ioremap(addr + offset, 4);
+ if (!ptr)
+ break;
+
/* The block id is stored in the 2nd word */
- if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
+ if (ptr[1] == 0x4752){
+ early_iounmap(ptr, 4);
/* set the pointer past the offset & block id */
- rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
+ ptr = early_ioremap(addr + offset + 4,
+ sizeof(struct rio_table_hdr));
+ rio_table_hdr = (struct rio_table_hdr *)ptr;
break;
}
prev_offset = offset;
- offset = *((unsigned short *)(ptr + offset));
+ offset = ptr[0];
+ early_iounmap(ptr, 4);
}
if (!rio_table_hdr) {
printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
@@ -1384,6 +1397,8 @@
ret = build_detail_arrays();
if (ret) {
printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
+ early_iounmap((void *)rio_table_hdr,
+ sizeof(struct rio_table_hdr));
return;
}
@@ -1423,6 +1438,10 @@
printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, "
"CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size,
debugging ? "enabled" : "disabled");
+ /* rio_table_hdr will be unmapped in calgary_locate_bbars() */
+ } else {
+ early_iounmap((void *)rio_table_hdr,
+ sizeof(struct rio_table_hdr));
}
return;
@@ -1433,6 +1452,7 @@
if (info->tce_space)
free_tce_table(info->tce_space);
}
+ early_iounmap((void *)rio_table_hdr, sizeof(struct rio_table_hdr));
}
int __init calgary_iommu_init(void)
Index: linux-2.6.git/arch/x86/kernel/setup_32.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/setup_32.c 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/setup_32.c 2008-01-08 03:43:46.000000000 -0800
@@ -61,7 +61,7 @@
#include <asm/io.h>
#include <asm/vmi.h>
#include <setup_arch.h>
-#include <bios_ebda.h>
+#include <asm/bios_ebda.h>
#include <asm/cacheflush.h>
/* This value is set up by the early boot code to point to the value
Index: linux-2.6.git/arch/x86/kernel/setup_64.c
===================================================================
--- linux-2.6.git.orig/arch/x86/kernel/setup_64.c 2008-01-08 03:41:30.000000000 -0800
+++ linux-2.6.git/arch/x86/kernel/setup_64.c 2008-01-08 03:47:57.000000000 -0800
@@ -62,6 +62,7 @@
#include <asm/sections.h>
#include <asm/dmi.h>
#include <asm/cacheflush.h>
+#include <asm/bios_ebda.h>
#include <asm/mce.h>
#include <asm/ds.h>
@@ -243,31 +244,36 @@
{}
#endif
-#define EBDA_ADDR_POINTER 0x40E
-
unsigned __initdata ebda_addr;
unsigned __initdata ebda_size;
static void discover_ebda(void)
{
+ unsigned short *ptr;
/*
* there is a real-mode segmented pointer pointing to the
* 4K EBDA area at 0x40E
*/
- ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
/*
* There can be some situations, like paravirtualized guests,
* in which there is no available ebda information. In such
* case, just skip it
*/
+
+ ebda_addr = get_bios_ebda();
if (!ebda_addr) {
ebda_size = 0;
return;
}
- ebda_addr <<= 4;
-
- ebda_size = *(unsigned short *)__va(ebda_addr);
+ ptr = (unsigned short *)__acpi_map_table(ebda_addr, 2);
+ if (!ptr) {
+ ebda_addr = 0;
+ ebda_size = 0;
+ return;
+ }
+ ebda_size = *(unsigned short *)ptr;
+ __acpi_unmap_table((char *)ptr, 2);
/* Round EBDA up to pages */
if (ebda_size == 0)
Index: linux-2.6.git/include/asm-x86/bios_ebda.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.git/include/asm-x86/bios_ebda.h 2008-01-08 03:43:46.000000000 -0800
@@ -0,0 +1,26 @@
+
+#ifndef _BIOS_EBDA_H
+#define _BIOS_EBDA_H
+
+#include <linux/acpi.h>
+
+/*
+ * there is a real-mode segmented pointer pointing to the
+ * 4K EBDA area at 0x40E.
+ */
+static inline unsigned long get_bios_ebda(void)
+{
+ unsigned short *bp;
+ unsigned long address;
+ bp = (unsigned short *)__acpi_map_table(0x40EUL, 2);
+ if (!bp)
+ return 0;
+
+ address = *bp;
+ address <<= 4;
+ __acpi_unmap_table((char *)bp, 2);
+
+ return address;
+}
+
+#endif /* _MACH_BIOS_EBDA_H */
Index: linux-2.6.git/include/asm-x86/mach-default/bios_ebda.h
===================================================================
--- linux-2.6.git.orig/include/asm-x86/mach-default/bios_ebda.h 2008-01-08 03:31:38.000000000 -0800
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-#ifndef _MACH_BIOS_EBDA_H
-#define _MACH_BIOS_EBDA_H
-
-/*
- * there is a real-mode segmented pointer pointing to the
- * 4K EBDA area at 0x40E.
- */
-static inline unsigned int get_bios_ebda(void)
-{
- unsigned int address = *(unsigned short *)phys_to_virt(0x40E);
- address <<= 4;
- return address; /* 0 means none */
-}
-
-#endif /* _MACH_BIOS_EBDA_H */
--
next prev parent reply other threads:[~2008-01-10 18:55 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-10 18:48 [patch 00/11] PAT x86: PAT support for x86 venkatesh.pallipadi
2008-01-10 18:48 ` venkatesh.pallipadi [this message]
2008-01-10 18:48 ` [patch 02/11] PAT x86: Map only usable memory in x86_64 identity map and kernel text venkatesh.pallipadi
2008-01-10 19:06 ` Andi Kleen
2008-01-10 19:17 ` Pallipadi, Venkatesh
2008-01-10 19:28 ` Andi Kleen
2008-01-10 20:50 ` Pallipadi, Venkatesh
2008-01-10 21:16 ` Andi Kleen
2008-01-10 22:25 ` Pallipadi, Venkatesh
2008-01-10 22:35 ` Andi Kleen
2008-01-14 16:43 ` Ingo Molnar
2008-01-14 21:21 ` Siddha, Suresh B
2008-01-14 21:28 ` Andi Kleen
2008-01-15 22:17 ` Ingo Molnar
2008-01-15 23:11 ` Andi Kleen
2008-01-15 23:21 ` Siddha, Suresh B
2008-01-18 12:01 ` Ingo Molnar
2008-01-18 13:12 ` Andi Kleen
2008-01-18 16:46 ` Jesse Barnes
2008-01-18 18:12 ` Andi Kleen
2008-01-18 19:02 ` Jesse Barnes
2008-01-19 2:42 ` Andi Kleen
2008-01-10 21:05 ` Linus Torvalds
2008-01-10 21:57 ` Pallipadi, Venkatesh
2008-01-10 22:15 ` Linus Torvalds
2008-01-10 22:27 ` Pallipadi, Venkatesh
2008-01-10 22:50 ` Valdis.Kletnieks
2008-01-18 18:27 ` Dave Jones
2008-01-18 20:54 ` Ingo Molnar
2008-01-10 18:48 ` [patch 03/11] PAT x86: Map only usable memory in i386 identity map venkatesh.pallipadi
2008-01-10 19:10 ` Andi Kleen
2008-01-10 18:48 ` [patch 04/11] PAT x86: Basic PAT implementation venkatesh.pallipadi
2008-01-10 18:48 ` [patch 05/11] PAT x86: drm driver changes for PAT venkatesh.pallipadi
2008-01-10 18:48 ` [patch 06/11] PAT x86: Refactoring i386 cpa venkatesh.pallipadi
2008-01-10 19:00 ` Andi Kleen
2008-01-14 16:47 ` Ingo Molnar
2008-01-10 18:48 ` [patch 07/11] PAT x86: pat-conflict resolution using linear list venkatesh.pallipadi
2008-01-10 19:13 ` Andi Kleen
2008-01-10 20:08 ` Pallipadi, Venkatesh
2008-01-10 18:48 ` [patch 08/11] PAT x86: pci mmap conlfict patch venkatesh.pallipadi
2008-01-10 18:48 ` [patch 09/11] PAT x86: Add ioremap_wc support venkatesh.pallipadi
2008-01-10 19:08 ` Andi Kleen
2008-01-10 19:25 ` Pallipadi, Venkatesh
2008-01-12 0:18 ` Roland Dreier
2008-01-10 18:48 ` [patch 10/11] PAT x86: Handle /dev/mem mappings venkatesh.pallipadi
2008-01-10 18:48 ` [patch 11/11] PAT x86: Expose uc and wc interfaces in /sysfs vor pci_mmap_resource venkatesh.pallipadi
2008-01-10 19:43 ` Greg KH
2008-01-10 20:54 ` [patch 11/11] PAT x86: Expose uc and wc interfaces in /sysfsvor pci_mmap_resource Pallipadi, Venkatesh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080110184854.557190000@intel.com \
--to=venkatesh.pallipadi@intel.com \
--cc=airlied@skynet.ie \
--cc=ak@muc.de \
--cc=akpm@linux-foundation.org \
--cc=arjan@infradead.org \
--cc=davej@redhat.com \
--cc=davem@davemloft.net \
--cc=ebiederm@xmission.com \
--cc=gregkh@suse.de \
--cc=hpa@zytor.com \
--cc=jesse.barnes@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rdreier@cisco.com \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.