Name: Neater returns for i386/x86_64 cpuid/msr on Offline CPUs Status: Untested Depends: Depends: Misc/on_one_cpu.patch.gz You can open an MSR or CPUID file on a cpu, and then it can go down. You'll get junk/noop; nicer to return an error on read/write in this case. Use on_one_cpu() as well. It's just easier to read. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .8202-linux-2.6.6-bk6/arch/i386/kernel/cpuid.c .8202-linux-2.6.6-bk6.updated/arch/i386/kernel/cpuid.c --- .8202-linux-2.6.6-bk6/arch/i386/kernel/cpuid.c 2004-05-20 19:40:03.000000000 +1000 +++ .8202-linux-2.6.6-bk6.updated/arch/i386/kernel/cpuid.c 2004-05-20 19:52:36.000000000 +1000 @@ -42,48 +42,33 @@ #include #include -#ifdef CONFIG_SMP - struct cpuid_command { - int cpu; + int err; u32 reg; u32 *data; }; -static void cpuid_smp_cpuid(void *cmd_block) +static inline void __do_cpuid(void *cmd_block) { struct cpuid_command *cmd = (struct cpuid_command *)cmd_block; - if (cmd->cpu == smp_processor_id()) - cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], - &cmd->data[3]); + cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], + &cmd->data[3]); + cmd->err = 0; } -static inline void do_cpuid(int cpu, u32 reg, u32 * data) +static inline int do_cpuid(int cpu, u32 reg, u32 * data) { struct cpuid_command cmd; - preempt_disable(); - if (cpu == smp_processor_id()) { - cpuid(reg, &data[0], &data[1], &data[2], &data[3]); - } else { - cmd.cpu = cpu; - cmd.reg = reg; - cmd.data = data; - - smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1); - } - preempt_enable(); -} -#else /* ! CONFIG_SMP */ + cmd.reg = reg; + cmd.data = data; + cmd.err = -ENOENT; -static inline void do_cpuid(int cpu, u32 reg, u32 * data) -{ - cpuid(reg, &data[0], &data[1], &data[2], &data[3]); + on_one_cpu(cpu, __do_cpuid, &cmd); + return cmd.err; } -#endif /* ! CONFIG_SMP */ - static loff_t cpuid_seek(struct file *file, loff_t offset, int orig) { loff_t ret; @@ -114,13 +99,15 @@ static ssize_t cpuid_read(struct file *f u32 data[4]; size_t rv; u32 reg = *ppos; - int cpu = iminor(file->f_dentry->d_inode); + int err, cpu = iminor(file->f_dentry->d_inode); if (count % 16) return -EINVAL; /* Invalid chunk size */ for (rv = 0; count; count -= 16) { - do_cpuid(cpu, reg, data); + err = do_cpuid(cpu, reg, data); + if (err) + return err; if (copy_to_user(tmp, &data, 16)) return -EFAULT; tmp += 4; diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .8202-linux-2.6.6-bk6/arch/i386/kernel/msr.c .8202-linux-2.6.6-bk6.updated/arch/i386/kernel/msr.c --- .8202-linux-2.6.6-bk6/arch/i386/kernel/msr.c 2004-05-20 19:40:03.000000000 +1000 +++ .8202-linux-2.6.6-bk6.updated/arch/i386/kernel/msr.c 2004-05-20 19:52:49.000000000 +1000 @@ -86,89 +86,53 @@ static inline int rdmsr_eio(u32 reg, u32 return err; } -#ifdef CONFIG_SMP - struct msr_command { - int cpu; int err; u32 reg; u32 data[2]; }; -static void msr_smp_wrmsr(void *cmd_block) +static inline void __msr_wrmsr(void *cmd_block) { struct msr_command *cmd = (struct msr_command *) cmd_block; - if ( cmd->cpu == smp_processor_id() ) - cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]); + cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]); } -static void msr_smp_rdmsr(void *cmd_block) +static inline void __msr_rdmsr(void *cmd_block) { struct msr_command *cmd = (struct msr_command *) cmd_block; - if ( cmd->cpu == smp_processor_id() ) - cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); + cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); } static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) { struct msr_command cmd; - int ret; - preempt_disable(); - if ( cpu == smp_processor_id() ) { - ret = wrmsr_eio(reg, eax, edx); - } else { - cmd.cpu = cpu; - cmd.reg = reg; - cmd.data[0] = eax; - cmd.data[1] = edx; - - smp_call_function(msr_smp_wrmsr, &cmd, 1, 1); - ret = cmd.err; - } - preempt_enable(); - return ret; + cmd.reg = reg; + cmd.data[0] = eax; + cmd.data[1] = edx; + cmd.err = -ENOENT; + + on_one_cpu(cpu, __msr_wrmsr, &cmd); + return cmd.err; } static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) { struct msr_command cmd; - int ret; - - preempt_disable(); - if ( cpu == smp_processor_id() ) { - ret = rdmsr_eio(reg, eax, edx); - } else { - cmd.cpu = cpu; - cmd.reg = reg; - - smp_call_function(msr_smp_rdmsr, &cmd, 1, 1); - - *eax = cmd.data[0]; - *edx = cmd.data[1]; - ret = cmd.err; - } - preempt_enable(); - return ret; -} - -#else /* ! CONFIG_SMP */ + cmd.reg = reg; + cmd.err = -ENOENT; -static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) -{ - return wrmsr_eio(reg, eax, edx); -} + on_one_cpu(cpu, __msr_rdmsr, &cmd); -static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) -{ - return rdmsr_eio(reg, eax, edx); + *eax = cmd.data[0]; + *edx = cmd.data[1]; + return cmd.err; } -#endif /* ! CONFIG_SMP */ - static loff_t msr_seek(struct file *file, loff_t offset, int orig) { loff_t ret = -EINVAL;