11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* mmu-context.c: MMU context allocation and management
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Written by David Howells (dhowells@redhat.com)
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation; either version
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 of the License, or (at your option) any later version.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/tlbflush.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NR_CXN	4096
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long cxn_bitmap[NR_CXN / (sizeof(unsigned long) * 8)];
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic LIST_HEAD(cxn_owners_lru);
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEFINE_SPINLOCK(cxn_owners_lock);
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __nongpreldata cxn_pinned = -1;
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * initialise a new context
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint init_new_context(struct task_struct *tsk, struct mm_struct *mm)
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&mm->context, 0, sizeof(mm->context));
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&mm->context.id_link);
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mm->context.itlb_cached_pge = 0xffffffffUL;
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mm->context.dtlb_cached_pge = 0xffffffffUL;
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end init_new_context() */
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * make sure a kernel MMU context has a CPU context number
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - call with cxn_owners_lock held
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned get_cxn(mm_context_t *ctx)
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head *_p;
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mm_context_t *p;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned cxn;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!list_empty(&ctx->id_link)) {
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_move_tail(&ctx->id_link, &cxn_owners_lru);
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* find the first unallocated context number
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * - 0 is reserved for the kernel
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
570f7217f4accad73e0a86febadb5a5d6e74ff7c37Akinobu Mita		cxn = find_next_zero_bit(cxn_bitmap, NR_CXN, 1);
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cxn < NR_CXN) {
590f7217f4accad73e0a86febadb5a5d6e74ff7c37Akinobu Mita			set_bit(cxn, cxn_bitmap);
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* none remaining - need to steal someone else's cxn */
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			p = NULL;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_for_each(_p, &cxn_owners_lru) {
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				p = list_entry(_p, mm_context_t, id_link);
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!p->id_busy && p->id != cxn_pinned)
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			BUG_ON(_p == &cxn_owners_lru);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cxn = p->id;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			p->id = 0;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_del_init(&p->id_link);
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			__flush_tlb_mm(cxn);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctx->id = cxn;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_add_tail(&ctx->id_link, &cxn_owners_lru);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ctx->id;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end get_cxn() */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * restore the current TLB miss handler mapped page tables into the MMU context and set up a
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mapping for the page directory
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *pgd)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long _pgd;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	_pgd = virt_to_phys(pgd);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* save the state of the outgoing MMU context */
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	old->id_busy = 0;
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movsg scr0,%0"   : "=r"(old->itlb_cached_pge));
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movsg dampr4,%0" : "=r"(old->itlb_ptd_mapping));
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movsg scr1,%0"   : "=r"(old->dtlb_cached_pge));
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movsg dampr5,%0" : "=r"(old->dtlb_ptd_mapping));
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* select an MMU context number */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&cxn_owners_lock);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	get_cxn(ctx);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctx->id_busy = 1;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&cxn_owners_lock);
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,cxnr"   : : "r"(ctx->id));
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* restore the state of the incoming MMU context */
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,scr0"   : : "r"(ctx->itlb_cached_pge));
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,dampr4" : : "r"(ctx->itlb_ptd_mapping));
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,scr1"   : : "r"(ctx->dtlb_cached_pge));
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,dampr5" : : "r"(ctx->dtlb_ptd_mapping));
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* map the PGD into uncached virtual memory */
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,ttbr"   : : "r"(_pgd));
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("movgs %0,dampr3"
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     :: "r"(_pgd | xAMPRx_L | xAMPRx_M | xAMPRx_SS_16Kb |
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    xAMPRx_S | xAMPRx_C | xAMPRx_V));
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end change_mm_context() */
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * finished with an MMU context number
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid destroy_context(struct mm_struct *mm)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mm_context_t *ctx = &mm->context;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&cxn_owners_lock);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!list_empty(&ctx->id_link)) {
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ctx->id == cxn_pinned)
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cxn_pinned = -1;
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_del_init(&ctx->id_link);
1410f7217f4accad73e0a86febadb5a5d6e74ff7c37Akinobu Mita		clear_bit(ctx->id, cxn_bitmap);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__flush_tlb_mm(ctx->id);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctx->id = 0;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&cxn_owners_lock);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end destroy_context() */
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * display the MMU context currently a process is currently using
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PROC_FS
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldschar *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer)
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&cxn_owners_lock);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer += sprintf(buffer, "CXNR: %u\n", mm->context.id);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&cxn_owners_lock);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return buffer;
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end proc_pid_status_frv_cxnr() */
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (un)pin a process's mm_struct's MMU context ID
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint cxn_pin_by_pid(pid_t pid)
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct task_struct *tsk;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mm_struct *mm = NULL;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* unpin if pid is zero */
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pid == 0) {
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cxn_pinned = -1;
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = -ESRCH;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* get a handle on the mm_struct */
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	read_lock(&tasklist_lock);
184540e3102f75dca9c5e614905527599de18294cc8Pavel Emelyanov	tsk = find_task_by_vpid(pid);
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tsk) {
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = -EINVAL;
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		task_lock(tsk);
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (tsk->mm) {
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mm = tsk->mm;
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_inc(&mm->mm_users);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = 0;
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		task_unlock(tsk);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	read_unlock(&tasklist_lock);
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret < 0)
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* make sure it has a CXN and pin it */
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&cxn_owners_lock);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cxn_pinned = get_cxn(&mm->context);
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&cxn_owners_lock);
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mmput(mm);
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* end cxn_pin_by_pid() */
209