Skip to content

Commit

Permalink
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (32 commits)
  x86: add MAP_STACK mmap flag
  x86: fix section mismatch warning - spp_getpage()
  x86: change init_gdt to update the gdt via write_gdt, rather than a direct write.
  x86-64: fix overlap of modules and fixmap areas
  x86, geode-mfgpt: check IRQ before using MFGPT as clocksource
  x86, acpi: cleanup, temp_stack is used only when CONFIG_SMP is set
  x86: fix spin_is_contended()
  x86, nmi: clean UP NMI watchdog failure message
  x86, NMI: fix watchdog failure message
  x86: fix /proc/meminfo DirectMap
  x86: fix readb() et al compile error with gcc-3.2.3
  arch/x86/Kconfig: clean up, experimental adjustement
  x86: invalidate caches before going into suspend
  x86, perfctr: don't use CCCR_OVF_PMI1 on Pentium 4Ds
  x86, AMD IOMMU: initialize dma_ops after sysfs registration
  x86m AMD IOMMU: cleanup: replace LOW_U32 macro with generic lower_32_bits
  x86, AMD IOMMU: initialize device table properly
  x86, AMD IOMMU: use status bit instead of memory write-back for completion wait
  x86: silence mmconfig printk
  x86, msr: fix NULL pointer deref due to msr_open on nonexistent CPUs
  ...
  • Loading branch information
Linus Torvalds committed Aug 17, 2008
2 parents 9e94cd3 + 2fdc869 commit 0473b79
Show file tree
Hide file tree
Showing 39 changed files with 299 additions and 149 deletions.
6 changes: 3 additions & 3 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -951,9 +951,9 @@ config NUMA
local memory controller of the CPU and add some more
NUMA awareness to the kernel.

For i386 this is currently highly experimental and should be only
For 32-bit this is currently highly experimental and should be only
used for kernel development. It might also cause boot failures.
For x86_64 this is recommended on all multiprocessor Opteron systems.
For 64-bit this is recommended on all multiprocessor Opteron systems.
If the system is EM64T, you should say N unless your system is
EM64T NUMA.

Expand Down Expand Up @@ -1263,7 +1263,7 @@ config KEXEC
strongly in flux, so no good recommendation can be made.

config CRASH_DUMP
bool "kernel crash dumps (EXPERIMENTAL)"
bool "kernel crash dumps"
depends on X86_64 || (X86_32 && HIGHMEM)
help
Generate crash dump after being started by kexec.
Expand Down
8 changes: 8 additions & 0 deletions arch/x86/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <linux/edd.h>
#include <asm/boot.h>
#include <asm/setup.h>
#include "bitops.h"
#include <asm/cpufeature.h>

/* Useful macros */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
Expand Down Expand Up @@ -242,6 +244,12 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);

/* cpu.c, cpucheck.c */
struct cpu_features {
int level; /* Family, or 64 for x86-64 */
int model;
u32 flags[NCAPINTS];
};
extern struct cpu_features cpu;
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
int validate_cpu(void);

Expand Down
3 changes: 0 additions & 3 deletions arch/x86/boot/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
*/

#include "boot.h"
#include "bitops.h"
#include <asm/cpufeature.h>

#include "cpustr.h"

static char *cpu_name(int level)
Expand Down
10 changes: 1 addition & 9 deletions arch/x86/boot/cpucheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,13 @@

#ifdef _SETUP
# include "boot.h"
# include "bitops.h"
#endif
#include <linux/types.h>
#include <asm/cpufeature.h>
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>

struct cpu_features {
int level; /* Family, or 64 for x86-64 */
int model;
u32 flags[NCAPINTS];
};

static struct cpu_features cpu;
struct cpu_features cpu;
static u32 cpu_vendor[3];
static u32 err_flags[NCAPINTS];

Expand Down
5 changes: 5 additions & 0 deletions arch/x86/boot/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ static void keyboard_set_repeat(void)
*/
static void query_ist(void)
{
/* Some older BIOSes apparently crash on this call, so filter
it from machines too old to have SpeedStep at all. */
if (cpu.level < 6)
return;

asm("int $0x15"
: "=a" (boot_params.ist_info.signature),
"=b" (boot_params.ist_info.command),
Expand Down
16 changes: 15 additions & 1 deletion arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
#warning ACPI uses CMPXCHG, i486 and later hardware
#endif

static int acpi_mcfg_64bit_base_addr __initdata = FALSE;

/* --------------------------------------------------------------------------
Boot-time Configuration
-------------------------------------------------------------------------- */
Expand Down Expand Up @@ -158,6 +160,14 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
struct acpi_mcfg_allocation *pci_mmcfg_config;
int pci_mmcfg_config_num;

static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
{
if (!strcmp(mcfg->header.oem_id, "SGI"))
acpi_mcfg_64bit_base_addr = TRUE;

return 0;
}

int __init acpi_parse_mcfg(struct acpi_table_header *header)
{
struct acpi_table_mcfg *mcfg;
Expand Down Expand Up @@ -190,8 +200,12 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header)
}

memcpy(pci_mmcfg_config, &mcfg[1], config_size);

acpi_mcfg_oem_check(mcfg);

for (i = 0; i < pci_mmcfg_config_num; ++i) {
if (pci_mmcfg_config[i].address > 0xFFFFFFFF) {
if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
!acpi_mcfg_64bit_base_addr) {
printk(KERN_ERR PREFIX
"MMCONFIG not in low 4GB of memory\n");
kfree(pci_mmcfg_config);
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ unsigned long acpi_realmode_flags;
/* address in low memory of the wakeup routine. */
static unsigned long acpi_realmode;

#ifdef CONFIG_64BIT
#if defined(CONFIG_SMP) && defined(CONFIG_64BIT)
static char temp_stack[10240];
#endif

Expand Down
19 changes: 11 additions & 8 deletions arch/x86/kernel/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,13 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
*/
static int iommu_completion_wait(struct amd_iommu *iommu)
{
int ret;
int ret, ready = 0;
unsigned status = 0;
struct iommu_cmd cmd;
volatile u64 ready = 0;
unsigned long ready_phys = virt_to_phys(&ready);
unsigned long i = 0;

memset(&cmd, 0, sizeof(cmd));
cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK;
cmd.data[1] = upper_32_bits(ready_phys);
cmd.data[2] = 1; /* value written to 'ready' */
cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);

iommu->need_sync = 0;
Expand All @@ -122,9 +119,15 @@ static int iommu_completion_wait(struct amd_iommu *iommu)

while (!ready && (i < EXIT_LOOP_COUNT)) {
++i;
cpu_relax();
/* wait for the bit to become one */
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
ready = status & MMIO_STATUS_COM_WAIT_INT_MASK;
}

/* set bit back to zero */
status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);

if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");

Expand Down Expand Up @@ -161,7 +164,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
address &= PAGE_MASK;
CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES);
cmd.data[1] |= domid;
cmd.data[2] = LOW_U32(address);
cmd.data[2] = lower_32_bits(address);
cmd.data[3] = upper_32_bits(address);
if (s) /* size bit - we flush more than one 4kb page */
cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
Expand Down
24 changes: 21 additions & 3 deletions arch/x86/kernel/amd_iommu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,21 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
return 0;
}

/*
* Init the device table to not allow DMA access for devices and
* suppress all page faults
*/
static void init_device_table(void)
{
u16 devid;

for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
set_dev_entry_bit(devid, DEV_ENTRY_VALID);
set_dev_entry_bit(devid, DEV_ENTRY_TRANSLATION);
set_dev_entry_bit(devid, DEV_ENTRY_NO_PAGE_FAULT);
}
}

/*
* This function finally enables all IOMMUs found in the system after
* they have been initialized
Expand Down Expand Up @@ -931,6 +946,9 @@ int __init amd_iommu_init(void)
if (amd_iommu_pd_alloc_bitmap == NULL)
goto free;

/* init the device table */
init_device_table();

/*
* let all alias entries point to itself
*/
Expand All @@ -954,15 +972,15 @@ int __init amd_iommu_init(void)
if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
goto free;

ret = amd_iommu_init_dma_ops();
ret = sysdev_class_register(&amd_iommu_sysdev_class);
if (ret)
goto free;

ret = sysdev_class_register(&amd_iommu_sysdev_class);
ret = sysdev_register(&device_amd_iommu);
if (ret)
goto free;

ret = sysdev_register(&device_amd_iommu);
ret = amd_iommu_init_dma_ops();
if (ret)
goto free;

Expand Down
8 changes: 0 additions & 8 deletions arch/x86/kernel/apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1454,8 +1454,6 @@ void disconnect_bsp_APIC(int virt_wire_setup)
}
}

unsigned int __cpuinitdata maxcpus = NR_CPUS;

void __cpuinit generic_processor_info(int apicid, int version)
{
int cpu;
Expand All @@ -1482,12 +1480,6 @@ void __cpuinit generic_processor_info(int apicid, int version)
return;
}

if (num_processors >= maxcpus) {
printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
" Processor ignored.\n", maxcpus);
return;
}

num_processors++;
cpus_complement(tmp_map, cpu_present_map);
cpu = first_cpu(tmp_map);
Expand Down
7 changes: 0 additions & 7 deletions arch/x86/kernel/apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ static unsigned long apic_phys;

unsigned long mp_lapic_addr;

unsigned int __cpuinitdata maxcpus = NR_CPUS;
/*
* Get the LAPIC version
*/
Expand Down Expand Up @@ -1062,12 +1061,6 @@ void __cpuinit generic_processor_info(int apicid, int version)
return;
}

if (num_processors >= maxcpus) {
printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
" Processor ignored.\n", maxcpus);
return;
}

num_processors++;
cpus_complement(tmp_map, cpu_present_map);
cpu = first_cpu(tmp_map);
Expand Down
8 changes: 7 additions & 1 deletion arch/x86/kernel/cpu/perfctr-watchdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,13 @@ static int setup_p4_watchdog(unsigned nmi_hz)
perfctr_msr = MSR_P4_IQ_PERFCTR1;
evntsel_msr = MSR_P4_CRU_ESCR0;
cccr_msr = MSR_P4_IQ_CCCR1;
cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);

/* Pentium 4 D processors don't support P4_CCCR_OVF_PMI1 */
if (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask == 4)
cccr_val = P4_CCCR_OVF_PMI0;
else
cccr_val = P4_CCCR_OVF_PMI1;
cccr_val |= P4_CCCR_ESCR_SELECT(4);
}

evntsel = P4_ESCR_EVENT_SELECT(0x3F)
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/genx2apic_uv_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static __init void map_low_mmrs(void)

enum map_type {map_wb, map_uc};

static void map_high(char *id, unsigned long base, int shift, enum map_type map_type)
static __init void map_high(char *id, unsigned long base, int shift, enum map_type map_type)
{
unsigned long bytes, paddr;

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
(__START_KERNEL & PGDIR_MASK)));
BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END);

/* clear bss before set_intr_gate with early_idt_handler */
clear_bss();
Expand Down
24 changes: 24 additions & 0 deletions arch/x86/kernel/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ static int hpet_clocksource_register(void)
int __init hpet_enable(void)
{
unsigned long id;
int i;

if (!is_hpet_capable())
return 0;
Expand All @@ -369,6 +370,29 @@ int __init hpet_enable(void)
* Read the period and check for a sane value:
*/
hpet_period = hpet_readl(HPET_PERIOD);

/*
* AMD SB700 based systems with spread spectrum enabled use a
* SMM based HPET emulation to provide proper frequency
* setting. The SMM code is initialized with the first HPET
* register access and takes some time to complete. During
* this time the config register reads 0xffffffff. We check
* for max. 1000 loops whether the config register reads a non
* 0xffffffff value to make sure that HPET is up and running
* before we go further. A counting loop is safe, as the HPET
* access takes thousands of CPU cycles. On non SB700 based
* machines this check is only done once and has no side
* effects.
*/
for (i = 0; hpet_readl(HPET_CFG) == 0xFFFFFFFF; i++) {
if (i == 1000) {
printk(KERN_WARNING
"HPET config register value = 0xFFFFFFFF. "
"Disabling HPET\n");
goto out_nohpet;
}
}

if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
goto out_nohpet;

Expand Down
Loading

0 comments on commit 0473b79

Please sign in to comment.