Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71b264f8 authored by Tony Luck's avatar Tony Luck
Browse files

Pull miscellaneous into release branch

Conflicts:

	arch/ia64/kernel/mca.c
parents f4df39cb 072f042d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -622,6 +622,9 @@ config IRQ_PER_CPU
	bool
	default y

config IOMMU_HELPER
	def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)

source "arch/ia64/hp/sim/Kconfig"

source "arch/ia64/Kconfig.debug"
+39 −17
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/nodemask.h>
#include <linux/bitops.h>         /* hweight64() */
#include <linux/crash_dump.h>
#include <linux/iommu-helper.h>

#include <asm/delay.h>		/* ia64_get_itc() */
#include <asm/io.h>
@@ -460,6 +461,13 @@ get_iovp_order (unsigned long size)
	return order;
}

static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
				 unsigned int bitshiftcnt)
{
	return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
		+ bitshiftcnt;
}

/**
 * sba_search_bitmap - find free space in IO PDIR resource bitmap
 * @ioc: IO MMU structure which owns the pdir we are interested in.
@@ -471,15 +479,25 @@ get_iovp_order (unsigned long size)
 * Cool perf optimization: search for log2(size) bits at a time.
 */
static SBA_INLINE unsigned long
sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
sba_search_bitmap(struct ioc *ioc, struct device *dev,
		  unsigned long bits_wanted, int use_hint)
{
	unsigned long *res_ptr;
	unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
	unsigned long flags, pide = ~0UL;
	unsigned long flags, pide = ~0UL, tpide;
	unsigned long boundary_size;
	unsigned long shift;
	int ret;

	ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
	ASSERT(res_ptr < res_end);

	boundary_size = (unsigned long long)dma_get_seg_boundary(dev) + 1;
	boundary_size = ALIGN(boundary_size, 1ULL << iovp_shift) >> iovp_shift;

	BUG_ON(ioc->ibase & ~iovp_mask);
	shift = ioc->ibase >> iovp_shift;

	spin_lock_irqsave(&ioc->res_lock, flags);

	/* Allow caller to force a search through the entire resource space */
@@ -504,9 +522,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
			if (likely(*res_ptr != ~0UL)) {
				bitshiftcnt = ffz(*res_ptr);
				*res_ptr |= (1UL << bitshiftcnt);
				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
				pide <<= 3;	/* convert to bit address */
				pide += bitshiftcnt;
				pide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
				ioc->res_bitshift = bitshiftcnt + bits_wanted;
				goto found_it;
			}
@@ -535,11 +551,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
			ASSERT(0 != mask);
			for (; mask ; mask <<= o, bitshiftcnt += o) {
				if(0 == ((*res_ptr) & mask)) {
				tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
				ret = iommu_is_span_boundary(tpide, bits_wanted,
							     shift,
							     boundary_size);
				if ((0 == ((*res_ptr) & mask)) && !ret) {
					*res_ptr |= mask;     /* mark resources busy! */
					pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
					pide <<= 3;	/* convert to bit address */
					pide += bitshiftcnt;
					pide = tpide;
					ioc->res_bitshift = bitshiftcnt + bits_wanted;
					goto found_it;
				}
@@ -560,6 +578,11 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
		end = res_end - qwords;

		for (; res_ptr < end; res_ptr++) {
			tpide = ptr_to_pide(ioc, res_ptr, 0);
			ret = iommu_is_span_boundary(tpide, bits_wanted,
						     shift, boundary_size);
			if (ret)
				goto next_ptr;
			for (i = 0 ; i < qwords ; i++) {
				if (res_ptr[i] != 0)
					goto next_ptr;
@@ -572,8 +595,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
				res_ptr[i] = ~0UL;
			res_ptr[i] |= RESMAP_MASK(bits);

			pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
			pide <<= 3;	/* convert to bit address */
			pide = tpide;
			res_ptr += qwords;
			ioc->res_bitshift = bits;
			goto found_it;
@@ -605,7 +627,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
 * resource bit map.
 */
static int
sba_alloc_range(struct ioc *ioc, size_t size)
sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{
	unsigned int pages_needed = size >> iovp_shift;
#ifdef PDIR_SEARCH_TIMING
@@ -622,9 +644,9 @@ sba_alloc_range(struct ioc *ioc, size_t size)
	/*
	** "seek and ye shall find"...praying never hurts either...
	*/
	pide = sba_search_bitmap(ioc, pages_needed, 1);
	pide = sba_search_bitmap(ioc, dev, pages_needed, 1);
	if (unlikely(pide >= (ioc->res_size << 3))) {
		pide = sba_search_bitmap(ioc, pages_needed, 0);
		pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
		if (unlikely(pide >= (ioc->res_size << 3))) {
#if DELAYED_RESOURCE_CNT > 0
			unsigned long flags;
@@ -653,7 +675,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
			}
			spin_unlock_irqrestore(&ioc->saved_lock, flags);

			pide = sba_search_bitmap(ioc, pages_needed, 0);
			pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
			if (unlikely(pide >= (ioc->res_size << 3)))
				panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
				      ioc->ioc_hpa);
@@ -936,7 +958,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, int dir)
	spin_unlock_irqrestore(&ioc->res_lock, flags);
#endif

	pide = sba_alloc_range(ioc, size);
	pide = sba_alloc_range(ioc, dev, size);

	iovp = (dma_addr_t) pide << iovp_shift;

@@ -1373,7 +1395,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev,
		dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask;
		ASSERT(dma_len <= DMA_CHUNK_SIZE);
		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
			| (sba_alloc_range(ioc, dma_len) << iovp_shift)
			| (sba_alloc_range(ioc, dev, dma_len) << iovp_shift)
			| dma_offset);
		n_mappings++;
	}
+7 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define ASM_OFFSETS_C 1

#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/clocksource.h>

#include <asm-ia64/processor.h>
@@ -34,6 +35,9 @@ void foo(void)
	DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe));
	DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));

	BUILD_BUG_ON(sizeof(struct upid) != 32);
	DEFINE(IA64_UPID_SHIFT, 5);

	BLANK();

	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
@@ -51,6 +55,9 @@ void foo(void)
	DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
	DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
	DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
	DEFINE(IA64_TASK_TGIDLINK_OFFSET, offsetof (struct task_struct, pids[PIDTYPE_PID].pid));
	DEFINE(IA64_PID_LEVEL_OFFSET, offsetof (struct pid, level));
	DEFINE(IA64_PID_UPID_OFFSET, offsetof (struct pid, numbers[0]));
	DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
	DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
	DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
+36 −20
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ int kdump_status[NR_CPUS];
static atomic_t kdump_cpu_frozen;
atomic_t kdump_in_progress;
static int kdump_on_init = 1;
static int kdump_on_fatal_mca = 1;

static inline Elf64_Word
*append_elf_note(Elf64_Word *buf, char *name, unsigned type, void *data,
@@ -118,6 +119,7 @@ machine_crash_shutdown(struct pt_regs *pt)
static void
machine_kdump_on_init(void)
{
	crash_save_vmcoreinfo();
	local_irq_disable();
	kexec_disable_iosapic();
	machine_kexec(ia64_kimage);
@@ -148,7 +150,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
	struct ia64_mca_notify_die *nd;
	struct die_args *args = data;

	if (!kdump_on_init)
	if (!kdump_on_init && !kdump_on_fatal_mca)
		return NOTIFY_DONE;

	if (!ia64_kimage) {
@@ -174,10 +176,13 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)

	switch (val) {
	case DIE_INIT_MONARCH_PROCESS:
		if (kdump_on_init) {
			atomic_set(&kdump_in_progress, 1);
			*(nd->monarch_cpu) = -1;
		}
		break;
	case DIE_INIT_MONARCH_LEAVE:
		if (kdump_on_init)
			machine_kdump_on_init();
		break;
	case DIE_INIT_SLAVE_LEAVE:
@@ -190,15 +195,18 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
		break;
	case DIE_MCA_MONARCH_LEAVE:
		/* die_register->signr indicate if MCA is recoverable */
			if (!args->signr)
		if (kdump_on_fatal_mca && !args->signr) {
			atomic_set(&kdump_in_progress, 1);
			*(nd->monarch_cpu) = -1;
			machine_kdump_on_init();
		}
		break;
	}
	return NOTIFY_DONE;
}

#ifdef CONFIG_SYSCTL
static ctl_table kdump_on_init_table[] = {
static ctl_table kdump_ctl_table[] = {
	{
		.ctl_name = CTL_UNNUMBERED,
		.procname = "kdump_on_init",
@@ -207,6 +215,14 @@ static ctl_table kdump_on_init_table[] = {
		.mode = 0644,
		.proc_handler = &proc_dointvec,
	},
	{
		.ctl_name = CTL_UNNUMBERED,
		.procname = "kdump_on_fatal_mca",
		.data = &kdump_on_fatal_mca,
		.maxlen = sizeof(int),
		.mode = 0644,
		.proc_handler = &proc_dointvec,
	},
	{ .ctl_name = 0 }
};

@@ -215,7 +231,7 @@ static ctl_table sys_table[] = {
	  .ctl_name = CTL_KERN,
	  .procname = "kernel",
	  .mode = 0555,
	  .child = kdump_on_init_table,
	  .child = kdump_ctl_table,
	},
	{ .ctl_name = 0 }
};
+30 −4
Original line number Diff line number Diff line
@@ -61,13 +61,29 @@ ENTRY(fsys_getpid)
	.prologue
	.altrp b6
	.body
	add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
	;;
	ld8 r17=[r17]				// r17 = current->group_leader
	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
	;;
	ld4 r9=[r9]
	add r8=IA64_TASK_TGID_OFFSET,r16
	add r17=IA64_TASK_TGIDLINK_OFFSET,r17
	;;
	and r9=TIF_ALLWORK_MASK,r9
	ld4 r8=[r8]				// r8 = current->tgid
	ld8 r17=[r17]				// r17 = current->group_leader->pids[PIDTYPE_PID].pid
	;;
	add r8=IA64_PID_LEVEL_OFFSET,r17
	;;
	ld4 r8=[r8]				// r8 = pid->level
	add r17=IA64_PID_UPID_OFFSET,r17	// r17 = &pid->numbers[0]
	;;
	shl r8=r8,IA64_UPID_SHIFT
	;;
	add r17=r17,r8				// r17 = &pid->numbers[pid->level]
	;;
	ld4 r8=[r17]				// r8 = pid->numbers[pid->level].nr
	;;
	mov r17=0
	;;
	cmp.ne p8,p0=0,r9
(p8)	br.spnt.many fsys_fallback_syscall
@@ -126,15 +142,25 @@ ENTRY(fsys_set_tid_address)
	.altrp b6
	.body
	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
	add r17=IA64_TASK_TGIDLINK_OFFSET,r16
	;;
	ld4 r9=[r9]
	tnat.z p6,p7=r32		// check argument register for being NaT
	ld8 r17=[r17]				// r17 = current->pids[PIDTYPE_PID].pid
	;;
	and r9=TIF_ALLWORK_MASK,r9
	add r8=IA64_TASK_PID_OFFSET,r16
	add r8=IA64_PID_LEVEL_OFFSET,r17
	add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16
	;;
	ld4 r8=[r8]
	ld4 r8=[r8]				// r8 = pid->level
	add r17=IA64_PID_UPID_OFFSET,r17	// r17 = &pid->numbers[0]
	;;
	shl r8=r8,IA64_UPID_SHIFT
	;;
	add r17=r17,r8				// r17 = &pid->numbers[pid->level]
	;;
	ld4 r8=[r17]				// r8 = pid->numbers[pid->level].nr
	;;
	cmp.ne p8,p0=0,r9
	mov r17=-1
	;;
Loading