Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/mattst88/alpha

Pull alpha updates from Matt Turner:
 "It contains a few fixes and some work from Richard to make alpha
  emulation under QEMU much more usable"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha:
  alpha: Prevent a NULL ptr dereference in csum_partial_copy.
  alpha: perf: fix out-of-bounds array access triggered from raw event
  alpha: Use qemu+cserve provided high-res clock and alarm.
  alpha: Switch to GENERIC_CLOCKEVENTS
  alpha: Enable the rpcc clocksource for single processor
  alpha: Reorganize rtc handling
  alpha: Primitive support for CPU power down.
  alpha: Allow HZ to be configured
  alpha: Notice if we're being run under QEMU
  alpha: Eliminate compiler warning from memset macro
  • Loading branch information
Linus Torvalds committed Nov 20, 2013
2 parents dc6ec87 + 5cfe8f1 commit d5bdaf4
Showing 24 changed files with 777 additions and 388 deletions.
76 changes: 73 additions & 3 deletions arch/alpha/Kconfig
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@ config ALPHA
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select GENERIC_CLOCKEVENTS
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select HAVE_MOD_ARCH_SPECIFIC
@@ -488,6 +488,20 @@ config VGA_HOSE
which always have multiple hoses, and whose consoles support it.


config ALPHA_QEMU
bool "Run under QEMU emulation"
depends on !ALPHA_GENERIC
---help---
Assume the presence of special features supported by QEMU PALcode
that reduce the overhead of system emulation.

Generic kernels will auto-detect QEMU. But when building a
system-specific kernel, the assumption is that we want to
elimiate as many runtime tests as possible.

If unsure, say N.


config ALPHA_SRM
bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
depends on TTY
@@ -572,6 +586,30 @@ config NUMA
Access). This option is for configuring high-end multiprocessor
server machines. If in doubt, say N.

config ALPHA_WTINT
bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
default y if ALPHA_QEMU
default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
default n if !ALPHA_SRM && !ALPHA_GENERIC
default y if SMP
---help---
The Wait for Interrupt (WTINT) PALcall attempts to place the CPU
to sleep until the next interrupt. This may reduce the power
consumed, and the heat produced by the computer. However, it has
the side effect of making the cycle counter unreliable as a timing
device across the sleep.

For emulation under QEMU, definitely say Y here, as we have other
mechanisms for measuring time than the cycle counter.

For EV4 (but not LCA), EV5 and EV56 systems, or for systems running
MILO, sleep mode is not supported so you might as well say N here.

For SMP systems we cannot use the cycle counter for timing anyway,
so you might as well say Y here.

If unsure, say N.

config NODES_SHIFT
int
default "7"
@@ -613,9 +651,41 @@ config VERBOSE_MCHECK_ON

Take the default (1) unless you want more control or more info.

choice
prompt "Timer interrupt frequency (HZ)?"
default HZ_128 if ALPHA_QEMU
default HZ_1200 if ALPHA_RAWHIDE
default HZ_1024
---help---
The frequency at which timer interrupts occur. A high frequency
minimizes latency, whereas a low frequency minimizes overhead of
process accounting. The later effect is especially significant
when being run under QEMU.

Note that some Alpha hardware cannot change the interrupt frequency
of the timer. If unsure, say 1024 (or 1200 for Rawhide).

config HZ_32
bool "32 Hz"
config HZ_64
bool "64 Hz"
config HZ_128
bool "128 Hz"
config HZ_256
bool "256 Hz"
config HZ_1024
bool "1024 Hz"
config HZ_1200
bool "1200 Hz"
endchoice

config HZ
int
default 1200 if ALPHA_RAWHIDE
int
default 32 if HZ_32
default 64 if HZ_64
default 128 if HZ_128
default 256 if HZ_256
default 1200 if HZ_1200
default 1024

source "drivers/pci/Kconfig"
22 changes: 13 additions & 9 deletions arch/alpha/include/asm/machvec.h
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ struct alpha_machine_vector

int nr_irqs;
int rtc_port;
int rtc_boot_cpu_only;
unsigned int max_asn;
unsigned long max_isa_dma_address;
unsigned long irq_probe_mask;
@@ -95,9 +96,6 @@ struct alpha_machine_vector

struct _alpha_agp_info *(*agp_info)(void);

unsigned int (*rtc_get_time)(struct rtc_time *);
int (*rtc_set_time)(struct rtc_time *);

const char *vector_name;

/* NUMA information */
@@ -126,13 +124,19 @@ extern struct alpha_machine_vector alpha_mv;

#ifdef CONFIG_ALPHA_GENERIC
extern int alpha_using_srm;
extern int alpha_using_qemu;
#else
#ifdef CONFIG_ALPHA_SRM
#define alpha_using_srm 1
#else
#define alpha_using_srm 0
#endif
# ifdef CONFIG_ALPHA_SRM
# define alpha_using_srm 1
# else
# define alpha_using_srm 0
# endif
# ifdef CONFIG_ALPHA_QEMU
# define alpha_using_qemu 1
# else
# define alpha_using_qemu 0
# endif
#endif /* GENERIC */

#endif
#endif /* __KERNEL__ */
#endif /* __ALPHA_MACHVEC_H */
71 changes: 71 additions & 0 deletions arch/alpha/include/asm/pal.h
Original file line number Diff line number Diff line change
@@ -89,6 +89,7 @@ __CALL_PAL_W1(wrmces, unsigned long);
__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
__CALL_PAL_W1(wrusp, unsigned long);
__CALL_PAL_W1(wrvptptr, unsigned long);
__CALL_PAL_RW1(wtint, unsigned long, unsigned long);

/*
* TB routines..
@@ -111,5 +112,75 @@ __CALL_PAL_W1(wrvptptr, unsigned long);
#define tbiap() __tbi(-1, /* no second argument */)
#define tbia() __tbi(-2, /* no second argument */)

/*
* QEMU Cserv routines..
*/

static inline unsigned long
qemu_get_walltime(void)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 3;

asm("call_pal %2 # cserve get_time"
: "=r"(v0), "+r"(a0)
: "i"(PAL_cserve)
: "$17", "$18", "$19", "$20", "$21");

return v0;
}

static inline unsigned long
qemu_get_alarm(void)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 4;

asm("call_pal %2 # cserve get_alarm"
: "=r"(v0), "+r"(a0)
: "i"(PAL_cserve)
: "$17", "$18", "$19", "$20", "$21");

return v0;
}

static inline void
qemu_set_alarm_rel(unsigned long expire)
{
register unsigned long a0 __asm__("$16") = 5;
register unsigned long a1 __asm__("$17") = expire;

asm volatile("call_pal %2 # cserve set_alarm_rel"
: "+r"(a0), "+r"(a1)
: "i"(PAL_cserve)
: "$0", "$18", "$19", "$20", "$21");
}

static inline void
qemu_set_alarm_abs(unsigned long expire)
{
register unsigned long a0 __asm__("$16") = 6;
register unsigned long a1 __asm__("$17") = expire;

asm volatile("call_pal %2 # cserve set_alarm_abs"
: "+r"(a0), "+r"(a1)
: "i"(PAL_cserve)
: "$0", "$18", "$19", "$20", "$21");
}

static inline unsigned long
qemu_get_vmtime(void)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 7;

asm("call_pal %2 # cserve get_time"
: "=r"(v0), "+r"(a0)
: "i"(PAL_cserve)
: "$17", "$18", "$19", "$20", "$21");

return v0;
}

#endif /* !__ASSEMBLY__ */
#endif /* __ALPHA_PAL_H */
11 changes: 0 additions & 11 deletions arch/alpha/include/asm/rtc.h
Original file line number Diff line number Diff line change
@@ -1,12 +1 @@
#ifndef _ALPHA_RTC_H
#define _ALPHA_RTC_H

#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \
|| defined(CONFIG_ALPHA_GENERIC)
# define get_rtc_time alpha_mv.rtc_get_time
# define set_rtc_time alpha_mv.rtc_set_time
#endif

#include <asm-generic/rtc.h>

#endif
24 changes: 18 additions & 6 deletions arch/alpha/include/asm/string.h
Original file line number Diff line number Diff line change
@@ -22,15 +22,27 @@ extern void * __memcpy(void *, const void *, size_t);

#define __HAVE_ARCH_MEMSET
extern void * __constant_c_memset(void *, unsigned long, size_t);
extern void * ___memset(void *, int, size_t);
extern void * __memset(void *, int, size_t);
extern void * memset(void *, int, size_t);

#define memset(s, c, n) \
(__builtin_constant_p(c) \
? (__builtin_constant_p(n) && (c) == 0 \
? __builtin_memset((s),0,(n)) \
: __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \
: __memset((s),(c),(n)))
/* For gcc 3.x, we cannot have the inline function named "memset" because
the __builtin_memset will attempt to resolve to the inline as well,
leading to a "sorry" about unimplemented recursive inlining. */
extern inline void *__memset(void *s, int c, size_t n)
{
if (__builtin_constant_p(c)) {
if (__builtin_constant_p(n)) {
return __builtin_memset(s, c, n);
} else {
unsigned long c8 = (c & 0xff) * 0x0101010101010101UL;
return __constant_c_memset(s, c8, n);
}
}
return ___memset(s, c, n);
}

#define memset __memset

#define __HAVE_ARCH_STRCPY
extern char * strcpy(char *,const char *);
1 change: 1 addition & 0 deletions arch/alpha/include/uapi/asm/pal.h
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@
#define PAL_rdusp 58
#define PAL_whami 60
#define PAL_retsys 61
#define PAL_wtint 62
#define PAL_rti 63


1 change: 1 addition & 0 deletions arch/alpha/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o
obj-$(CONFIG_SRM_ENV) += srm_env.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o

ifdef CONFIG_ALPHA_GENERIC

1 change: 1 addition & 0 deletions arch/alpha/kernel/alpha_ksyms.c
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ EXPORT_SYMBOL(strrchr);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(___memset);
EXPORT_SYMBOL(__memsetw);
EXPORT_SYMBOL(__constant_c_memset);
EXPORT_SYMBOL(copy_page);
16 changes: 1 addition & 15 deletions arch/alpha/kernel/irq_alpha.c
Original file line number Diff line number Diff line change
@@ -66,21 +66,7 @@ do_entInt(unsigned long type, unsigned long vector,
break;
case 1:
old_regs = set_irq_regs(regs);
#ifdef CONFIG_SMP
{
long cpu;

smp_percpu_timer_interrupt(regs);
cpu = smp_processor_id();
if (cpu != boot_cpuid) {
kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
} else {
handle_irq(RTC_IRQ);
}
}
#else
handle_irq(RTC_IRQ);
#endif
set_irq_regs(old_regs);
return;
case 2:
@@ -228,7 +214,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
*/

struct irqaction timer_irqaction = {
.handler = timer_interrupt,
.handler = rtc_timer_interrupt,
.name = "timer",
};

5 changes: 1 addition & 4 deletions arch/alpha/kernel/machvec_impl.h
Original file line number Diff line number Diff line change
@@ -43,10 +43,7 @@
#define CAT1(x,y) x##y
#define CAT(x,y) CAT1(x,y)

#define DO_DEFAULT_RTC \
.rtc_port = 0x70, \
.rtc_get_time = common_get_rtc_time, \
.rtc_set_time = common_set_rtc_time
#define DO_DEFAULT_RTC .rtc_port = 0x70

#define DO_EV4_MMU \
.max_asn = EV4_MAX_ASN, \
15 changes: 13 additions & 2 deletions arch/alpha/kernel/perf_event.c
Original file line number Diff line number Diff line change
@@ -83,6 +83,8 @@ struct alpha_pmu_t {
long pmc_left[3];
/* Subroutine for allocation of PMCs. Enforces constraints. */
int (*check_constraints)(struct perf_event **, unsigned long *, int);
/* Subroutine for checking validity of a raw event for this PMU. */
int (*raw_event_valid)(u64 config);
};

/*
@@ -203,6 +205,12 @@ static int ev67_check_constraints(struct perf_event **event,
}


static int ev67_raw_event_valid(u64 config)
{
return config >= EV67_CYCLES && config < EV67_LAST_ET;
};


static const struct alpha_pmu_t ev67_pmu = {
.event_map = ev67_perfmon_event_map,
.max_events = ARRAY_SIZE(ev67_perfmon_event_map),
@@ -211,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = {
.pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0},
.pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0},
.pmc_left = {16, 4, 0},
.check_constraints = ev67_check_constraints
.check_constraints = ev67_check_constraints,
.raw_event_valid = ev67_raw_event_valid,
};


@@ -609,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event)
} else if (attr->type == PERF_TYPE_HW_CACHE) {
return -EOPNOTSUPP;
} else if (attr->type == PERF_TYPE_RAW) {
ev = attr->config & 0xff;
if (!alpha_pmu->raw_event_valid(attr->config))
return -EINVAL;
ev = attr->config;
} else {
return -EOPNOTSUPP;
}
Loading

0 comments on commit d5bdaf4

Please sign in to comment.