Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 100161
b: refs/heads/master
c: 6c82a00
h: refs/heads/master
i:
  100159: 257f13a
v: v3
  • Loading branch information
Ingo Molnar committed Jul 11, 2008
1 parent bdada5d commit 460a902
Show file tree
Hide file tree
Showing 31 changed files with 229 additions and 199 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 39415a440ecceb0a5bd3c23686f18f83bb8368c6
refs/heads/master: 6c82a000a29b93541b5b7db597a083c069755cc9
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp)
CFLAGS_hpet.o := $(nostackp)
CFLAGS_tsc_64.o := $(nostackp)
CFLAGS_tsc.o := $(nostackp)

obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
obj-y += traps_$(BITS).o irq_$(BITS).o
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
if (!phys || !size)
return NULL;

if (phys+size <= (max_pfn_mapped << PAGE_SHIFT))
if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
return __va(phys);

offset = phys & (PAGE_SIZE - 1);
Expand Down
10 changes: 7 additions & 3 deletions trunk/arch/x86/kernel/cpu/amd_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,14 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
* Don't do it for gbpages because there seems very little
* benefit in doing so.
*/
if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) &&
(tseg >> PMD_SHIFT) <
(max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT)))
if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
if ((tseg>>PMD_SHIFT) <
(max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) ||
((tseg>>PMD_SHIFT) <
(max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) &&
(tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
set_memory_4k((unsigned long)__va(tseg), 1);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/kernel/cpu/centaur_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
{
if (c->x86 == 0x6 && c->x86_model >= 0xf)
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);

set_cpu_cap(c, X86_FEATURE_SYSENTER32);
}

static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/cpu/common_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
if (c->extended_cpuid_level >= 0x80000007)
c->x86_power = cpuid_edx(0x80000007);

/* Assume all 64-bit CPUs support 32-bit syscall */
set_cpu_cap(c, X86_FEATURE_SYSCALL32);

if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
cpu_devs[c->x86_vendor]->c_early_init)
cpu_devs[c->x86_vendor]->c_early_init(c);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/kernel/cpu/intel_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
(c->x86 == 0x6 && c->x86_model >= 0x0e))
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);

set_cpu_cap(c, X86_FEATURE_SYSENTER32);
}

/*
Expand Down
34 changes: 25 additions & 9 deletions trunk/arch/x86/kernel/e820.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,20 +1056,29 @@ unsigned long __initdata end_user_pfn = MAX_ARCH_PFN;
/*
* Find the highest page frame number we have available
*/
unsigned long __init e820_end(void)
static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
{
int i;
unsigned long last_pfn = 0;
unsigned long max_arch_pfn = MAX_ARCH_PFN;

for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
unsigned long start_pfn;
unsigned long end_pfn;

if (ei->type != E820_RAM)
if (ei->type != type)
continue;

start_pfn = ei->addr >> PAGE_SHIFT;
end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;

if (start_pfn >= limit_pfn)
continue;
if (end_pfn > limit_pfn) {
last_pfn = limit_pfn;
break;
}
if (end_pfn > last_pfn)
last_pfn = end_pfn;
}
Expand All @@ -1083,7 +1092,15 @@ unsigned long __init e820_end(void)
last_pfn, max_arch_pfn);
return last_pfn;
}
unsigned long __init e820_end_of_ram_pfn(void)
{
return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
}

unsigned long __init e820_end_of_low_ram_pfn(void)
{
return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
}
/*
* Finds an active region in the address range from start_pfn to last_pfn and
* returns its range in ei_startpfn and ei_endpfn for the e820 entry.
Expand Down Expand Up @@ -1165,6 +1182,8 @@ static void early_panic(char *msg)
panic(msg);
}

static int userdef __initdata;

/* "mem=nopentium" disables the 4MB page tables. */
static int __init parse_memopt(char *p)
{
Expand All @@ -1180,17 +1199,15 @@ static int __init parse_memopt(char *p)
}
#endif

userdef = 1;
mem_size = memparse(p, &p);
end_user_pfn = mem_size>>PAGE_SHIFT;
e820_update_range(mem_size, ULLONG_MAX - mem_size,
E820_RAM, E820_RESERVED);
e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);

return 0;
}
early_param("mem", parse_memopt);

static int userdef __initdata;

static int __init parse_memmap_opt(char *p)
{
char *oldp;
Expand All @@ -1206,7 +1223,7 @@ static int __init parse_memmap_opt(char *p)
* the real mem size before original memory map is
* reset.
*/
saved_max_pfn = e820_end();
saved_max_pfn = e820_end_of_ram_pfn();
#endif
e820.nr_map = 0;
userdef = 1;
Expand All @@ -1230,8 +1247,7 @@ static int __init parse_memmap_opt(char *p)
e820_add_region(start_at, mem_size, E820_RESERVED);
} else {
end_user_pfn = (mem_size >> PAGE_SHIFT);
e820_update_range(mem_size, ULLONG_MAX - mem_size,
E820_RAM, E820_RESERVED);
e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
}
return *p == '\0' ? 0 : -EINVAL;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ void __init efi_enter_virtual_mode(void)
size = md->num_pages << EFI_PAGE_SHIFT;
end = md->phys_addr + size;

if (PFN_UP(end) <= max_pfn_mapped)
if (PFN_UP(end) <= max_low_pfn_mapped)
va = __va(md->phys_addr);
else
va = efi_ioremap(md->phys_addr, size);
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/x86/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,7 @@ ENTRY(xen_sysenter_target)
RING0_INT_FRAME
addl $5*4, %esp /* remove xen-provided frame */
jmp sysenter_past_esp
CFI_ENDPROC

ENTRY(xen_hypervisor_callback)
CFI_STARTPROC
Expand Down
40 changes: 27 additions & 13 deletions trunk/arch/x86/kernel/io_apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2027,7 +2027,7 @@ static inline void init_IO_APIC_traps(void)
* The local APIC irq-chip implementation:
*/

static void ack_apic(unsigned int irq)
static void ack_lapic_irq(unsigned int irq)
{
ack_APIC_irq();
}
Expand All @@ -2052,9 +2052,17 @@ static struct irq_chip lapic_chip __read_mostly = {
.name = "local-APIC",
.mask = mask_lapic_irq,
.unmask = unmask_lapic_irq,
.eoi = ack_apic,
.ack = ack_lapic_irq,
};

static void lapic_register_intr(int irq, int vector)
{
irq_desc[irq].status &= ~IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
"edge");
set_intr_gate(vector, interrupt[irq]);
}

static void __init setup_nmi(void)
{
/*
Expand Down Expand Up @@ -2257,8 +2265,7 @@ static inline void __init check_timer(void)

printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");

set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq,
"fasteoi");
lapic_register_intr(0, vector);
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
enable_8259A_irq(0);

Expand Down Expand Up @@ -2290,11 +2297,21 @@ static inline void __init check_timer(void)
}

/*
*
* IRQ's that are handled by the PIC in the MPS IOAPIC case.
* - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
* Linux doesn't really care, as it's not actually used
* for any interrupt handling anyway.
* Traditionally ISA IRQ2 is the cascade IRQ, and is not available
* to devices. However there may be an I/O APIC pin available for
* this interrupt regardless. The pin may be left unconnected, but
* typically it will be reused as an ExtINT cascade interrupt for
* the master 8259A. In the MPS case such a pin will normally be
* reported as an ExtINT interrupt in the MP table. With ACPI
* there is no provision for ExtINT interrupts, and in the absence
* of an override it would be treated as an ordinary ISA I/O APIC
* interrupt, that is edge-triggered and unmasked by default. We
* used to do this, but it caused problems on some systems because
* of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
* the same ExtINT cascade interrupt to drive the local APIC of the
* bootstrap processor. Therefore we refrain from routing IRQ2 to
* the I/O APIC in all cases now. No actual device should request
* it anyway. --macro
*/
#define PIC_IRQS (1 << PIC_CASCADE_IR)

Expand All @@ -2308,10 +2325,7 @@ void __init setup_IO_APIC(void)

enable_IO_APIC();

if (acpi_ioapic)
io_apic_irqs = ~0; /* all IRQs go through IOAPIC */
else
io_apic_irqs = ~PIC_IRQS;
io_apic_irqs = ~PIC_IRQS;

printk("ENABLING IO-APIC IRQs\n");

Expand Down
54 changes: 31 additions & 23 deletions trunk/arch/x86/kernel/io_apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,15 +1561,15 @@ static inline void init_IO_APIC_traps(void)
}
}

static void enable_lapic_irq (unsigned int irq)
static void unmask_lapic_irq(unsigned int irq)
{
unsigned long v;

v = apic_read(APIC_LVT0);
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
}

static void disable_lapic_irq (unsigned int irq)
static void mask_lapic_irq(unsigned int irq)
{
unsigned long v;

Expand All @@ -1582,19 +1582,20 @@ static void ack_lapic_irq (unsigned int irq)
ack_APIC_irq();
}

static void end_lapic_irq (unsigned int i) { /* nothing */ }

static struct hw_interrupt_type lapic_irq_type __read_mostly = {
.name = "local-APIC",
.typename = "local-APIC-edge",
.startup = NULL, /* startup_irq() not used for IRQ0 */
.shutdown = NULL, /* shutdown_irq() not used for IRQ0 */
.enable = enable_lapic_irq,
.disable = disable_lapic_irq,
.ack = ack_lapic_irq,
.end = end_lapic_irq,
static struct irq_chip lapic_chip __read_mostly = {
.name = "local-APIC",
.mask = mask_lapic_irq,
.unmask = unmask_lapic_irq,
.ack = ack_lapic_irq,
};

static void lapic_register_intr(int irq)
{
irq_desc[irq].status &= ~IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
"edge");
}

static void __init setup_nmi(void)
{
/*
Expand Down Expand Up @@ -1784,7 +1785,7 @@ static inline void __init check_timer(void)

apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");

irq_desc[0].chip = &lapic_irq_type;
lapic_register_intr(0);
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
enable_8259A_irq(0);

Expand Down Expand Up @@ -1822,11 +1823,21 @@ static int __init notimercheck(char *s)
__setup("no_timer_check", notimercheck);

/*
*
* IRQs that are handled by the PIC in the MPS IOAPIC case.
* - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
* Linux doesn't really care, as it's not actually used
* for any interrupt handling anyway.
* Traditionally ISA IRQ2 is the cascade IRQ, and is not available
* to devices. However there may be an I/O APIC pin available for
* this interrupt regardless. The pin may be left unconnected, but
* typically it will be reused as an ExtINT cascade interrupt for
* the master 8259A. In the MPS case such a pin will normally be
* reported as an ExtINT interrupt in the MP table. With ACPI
* there is no provision for ExtINT interrupts, and in the absence
* of an override it would be treated as an ordinary ISA I/O APIC
* interrupt, that is edge-triggered and unmasked by default. We
* used to do this, but it caused problems on some systems because
* of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
* the same ExtINT cascade interrupt to drive the local APIC of the
* bootstrap processor. Therefore we refrain from routing IRQ2 to
* the I/O APIC in all cases now. No actual device should request
* it anyway. --macro
*/
#define PIC_IRQS (1<<2)

Expand All @@ -1837,10 +1848,7 @@ void __init setup_IO_APIC(void)
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
*/

if (acpi_ioapic)
io_apic_irqs = ~0; /* all IRQs go through IOAPIC */
else
io_apic_irqs = ~PIC_IRQS;
io_apic_irqs = ~PIC_IRQS;

apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");

Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ int __init check_nmi_watchdog(void)
error:
if (nmi_watchdog == NMI_IO_APIC && !timer_through_8259)
disable_8259A_irq(0);
#ifdef CONFIG_X86_32
timer_ack = 0;
#endif
return -1;
}

Expand Down
Loading

0 comments on commit 460a902

Please sign in to comment.