X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fkernel%2Fppc_htab.c;h=ad7808fa6a83afb5d9836fd3ab46c20030c55a03;hb=1be35e94e1da3669db492995cd2c8b1a37016b11;hp=91592c03ea8bb18eee5ccbf76eef6c5d72ae0dbf;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 91592c03e..ad7808fa6 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -31,11 +30,13 @@ #include #include -static int ppc_htab_show(struct seq_file *m, void *v); +static ssize_t ppc_htab_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos); static ssize_t ppc_htab_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos); +static long long ppc_htab_lseek(struct file * file, loff_t offset, int orig); int proc_dol2crvec(ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos); + void __user *buffer, size_t *lenp); extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; @@ -48,17 +49,10 @@ extern unsigned long pte_errors; extern unsigned int primary_pteg_full; extern unsigned int htab_hash_searches; -static int ppc_htab_open(struct inode *inode, struct file *file) -{ - return single_open(file, ppc_htab_show, NULL); -} - struct file_operations ppc_htab_operations = { - .open = ppc_htab_open, - .read = seq_read, - .llseek = seq_lseek, - .write = ppc_htab_write, - .release = single_release, + .llseek = ppc_htab_lseek, + .read = ppc_htab_read, + .write = ppc_htab_write, }; static char *pmc1_lookup(unsigned long mmcr0) @@ -102,25 +96,31 @@ static char *pmc2_lookup(unsigned long mmcr0) * is _REALLY_ slow (see the nested for loops below) but nothing * in here should be really timing critical. -- Cort */ -static int ppc_htab_show(struct seq_file *m, void *v) +static ssize_t ppc_htab_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) { unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; + int n = 0; #if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE) unsigned int kptes = 0, uptes = 0; PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ + char buffer[512]; + + if (count < 0) + return -EINVAL; if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { mmcr0 = mfspr(SPRN_MMCR0); pmc1 = mfspr(SPRN_PMC1); pmc2 = mfspr(SPRN_PMC2); - seq_printf(m, + n += sprintf( buffer + n, "604 Performance Monitoring\n" "MMCR0\t\t: %08lx %s%s ", mmcr0, ( mmcr0>>28 & 0x2 ) ? "(user mode counted)" : "", ( mmcr0>>28 & 0x4 ) ? "(kernel mode counted)" : ""); - seq_printf(m, + n += sprintf( buffer + n, "\nPMC1\t\t: %08lx (%s)\n" "PMC2\t\t: %08lx (%s)\n", pmc1, pmc1_lookup(mmcr0), @@ -129,9 +129,10 @@ static int ppc_htab_show(struct seq_file *m, void *v) #ifdef CONFIG_PPC_STD_MMU /* if we don't have a htab */ - if ( Hash_size == 0 ) { - seq_printf(m, "No Hash Table used\n"); - return 0; + if ( Hash_size == 0 ) + { + n += sprintf( buffer + n, "No Hash Table used\n"); + goto return_string; } #ifndef CONFIG_PPC64BRIDGE @@ -150,7 +151,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) } #endif - seq_printf(m, + n += sprintf( buffer + n, "PTE Hash Table Information\n" "Size\t\t: %luKb\n" "Buckets\t\t: %lu\n" @@ -172,7 +173,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) #endif ); - seq_printf(m, + n += sprintf( buffer + n, "Reloads\t\t: %lu\n" "Preloads\t: %lu\n" "Searches\t: %u\n" @@ -180,13 +181,23 @@ static int ppc_htab_show(struct seq_file *m, void *v) "Evicts\t\t: %lu\n", htab_reloads, htab_preloads, htab_hash_searches, primary_pteg_full, htab_evicts); +return_string: #endif /* CONFIG_PPC_STD_MMU */ - seq_printf(m, + n += sprintf( buffer + n, "Non-error misses: %lu\n" "Error misses\t: %lu\n", pte_misses, pte_errors); - return 0; + if (*ppos >= strlen(buffer)) + return 0; + if (n > strlen(buffer) - *ppos) + n = strlen(buffer) - *ppos; + if (n > count) + n = count; + if (copy_to_user(buf, buffer + *ppos, n)) + return -EFAULT; + *ppos += n; + return n; } /* @@ -199,7 +210,7 @@ static ssize_t ppc_htab_write(struct file * file, const char __user * ubuffer, unsigned long tmp; char buffer[16]; - if (!capable(CAP_SYS_ADMIN)) + if ( current->uid != 0 ) return -EACCES; if (strncpy_from_user(buffer, ubuffer, 15)) return -EFAULT; @@ -319,8 +330,28 @@ static ssize_t ppc_htab_write(struct file * file, const char __user * ubuffer, #endif /* CONFIG_PPC_STD_MMU */ } + +static long long +ppc_htab_lseek(struct file * file, loff_t offset, int orig) +{ + long long ret = -EINVAL; + + lock_kernel(); + switch (orig) { + case 0: + file->f_pos = offset; + ret = file->f_pos; + break; + case 1: + file->f_pos += offset; + ret = file->f_pos; + } + unlock_kernel(); + return ret; +} + int proc_dol2crvec(ctl_table *table, int write, struct file *filp, - void __user *buffer_arg, size_t *lenp, loff_t *ppos) + void __user *buffer_arg, size_t *lenp) { int vleft, first=1, len, left, val; char __user *buffer = (char __user *) buffer_arg; @@ -344,7 +375,7 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp, if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) return -EFAULT; - if ( /*!table->maxlen ||*/ (*ppos && !write)) { + if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) { *lenp = 0; return 0; } @@ -417,15 +448,15 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp, } if (!write && !first && left) { - if(put_user('\n', (char __user *) buffer)) + if(put_user('\n', (char *) buffer)) return -EFAULT; left--, buffer++; } if (write) { - char __user *s = (char __user *) buffer; + p = (char *) buffer; while (left) { char c; - if(get_user(c, s++)) + if(get_user(c, p++)) return -EFAULT; if (!isspace(c)) break; @@ -435,6 +466,6 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp, if (write && first) return -EINVAL; *lenp -= left; - *ppos += *lenp; + filp->f_pos += *lenp; return 0; }