⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 microcode.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
	while (cursor + MC_HEADER_SIZE < user_buffer_size) {		microcode_header_t mc_header;		void *newmc = NULL;		int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size;		if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) {			printk(KERN_ERR "microcode: error! Can not read user data\n");			error = -EFAULT;			goto out;		}		total_size = get_totalsize(&mc_header);		if (cursor + total_size > user_buffer_size) {			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");			error = -EINVAL;			goto out;		}		data_size = get_datasize(&mc_header);		if (data_size + MC_HEADER_SIZE > total_size) {			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");			error = -EINVAL;			goto out;		}		if (mc_header.ldrver != 1 || mc_header.hdrver != 1) {			printk(KERN_ERR "microcode: error! Unknown microcode update format\n");			error = -EINVAL;			goto out;		}		for_each_online_cpu(cpu_num) {			struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;			if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf))				mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum);		}		ext_table_size = total_size - (MC_HEADER_SIZE + data_size);		if (ext_table_size) {			struct extended_sigtable ext_header;			struct extended_signature ext_sig;			int ext_sigcount;			if ((ext_table_size < EXT_HEADER_SIZE) 					|| ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {				printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");				error = -EINVAL;				goto out;			}			if (copy_from_user(&ext_header, user_buffer + cursor 					+ MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) {				printk(KERN_ERR "microcode: error! Can not read user data\n");				error = -EFAULT;				goto out;			}			if (ext_table_size != exttable_size(&ext_header)) {				printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");				error = -EFAULT;				goto out;			}			ext_sigcount = ext_header.count;						for (i = 0; i < ext_sigcount; i++) {				if (copy_from_user(&ext_sig, user_buffer + cursor + MC_HEADER_SIZE + data_size + EXT_HEADER_SIZE 						+ EXT_SIGNATURE_SIZE * i, EXT_SIGNATURE_SIZE)) {					printk(KERN_ERR "microcode: error! Can not read user data\n");					error = -EFAULT;					goto out;				}				for_each_online_cpu(cpu_num) {					struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;					if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) {						mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);					}				}			}		}		/* now check if any cpu has matched */		allocated_flag = 0;		sum = 0;		for_each_online_cpu(cpu_num) {			if (ucode_cpu_info[cpu_num].err == MC_MARKED) { 				struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;				if (!allocated_flag) {					allocated_flag = 1;					newmc = vmalloc(total_size);					if (!newmc) {						printk(KERN_ERR "microcode: error! Can not allocate memory\n");						error = -ENOMEM;						goto out;					}					if (copy_from_user(newmc + MC_HEADER_SIZE, 								user_buffer + cursor + MC_HEADER_SIZE, 								total_size - MC_HEADER_SIZE)) {						printk(KERN_ERR "microcode: error! Can not read user data\n");						vfree(newmc);						error = -EFAULT;						goto out;					}					memcpy(newmc, &mc_header, MC_HEADER_SIZE);					/* check extended table checksum */					if (ext_table_size) {						int ext_table_sum = 0;						int * ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size);						i = ext_table_size / DWSIZE;						while (i--) ext_table_sum += ext_tablep[i];						if (ext_table_sum) {							printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n");							vfree(newmc);							error = -EINVAL;							goto out;						}					}					/* calculate the checksum */					i = (MC_HEADER_SIZE + data_size) / DWSIZE;					while (i--) sum += ((int *)newmc)[i];					sum -= (mc_header.sig + mc_header.pf + mc_header.cksum);				}				ucode_cpu_info[cpu_num].mc = newmc;				ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */				if (sum + uci->sig + uci->pf + uci->cksum != 0) {					printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num);					error = -EINVAL;					goto out;				}			}		}		cursor += total_size; /* goto the next update patch */	} /* end of while */out:	return error;}static void do_update_one (void * unused){	unsigned long flags;	unsigned int val[2];	int cpu_num = smp_processor_id();	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;	if (uci->mc == NULL) {		if (verbose) {			if (uci->err == MC_SUCCESS)				printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n",					cpu_num, uci->rev);			else				printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num);		}		return;	}	/* serialize access to the physical write to MSR 0x79 */	spin_lock_irqsave(&microcode_update_lock, flags);          	/* write microcode via MSR 0x79 */	wrmsr(MSR_IA32_UCODE_WRITE,		(unsigned long) uci->mc->bits, 		(unsigned long) uci->mc->bits >> 16 >> 16);	wrmsr(MSR_IA32_UCODE_REV, 0, 0);	/* see notes above for revision 1.07.  Apparent chip bug */	sync_core();	/* get the current revision from MSR 0x8B */	rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);	/* notify the caller of success on this cpu */	uci->err = MC_SUCCESS;	spin_unlock_irqrestore(&microcode_update_lock, flags);	printk(KERN_INFO "microcode: CPU%d updated from revision "	       "0x%x to 0x%x, date = %08x \n", 	       cpu_num, uci->rev, val[1], uci->mc->hdr.date);	return;}static int do_microcode_update (void){	int i, error;	if (on_each_cpu(collect_cpu_info, NULL, 1, 1) != 0) {		printk(KERN_ERR "microcode: Error! Could not run on all processors\n");		error = -EIO;		goto out;	}	if ((error = find_matching_ucodes())) {		printk(KERN_ERR "microcode: Error in the microcode data\n");		goto out_free;	}	if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) {		printk(KERN_ERR "microcode: Error! Could not run on all processors\n");		error = -EIO;	}out_free:	for_each_online_cpu(i) {		if (ucode_cpu_info[i].mc) {			int j;			void *tmp = ucode_cpu_info[i].mc;			vfree(tmp);			for_each_online_cpu(j) {				if (ucode_cpu_info[j].mc == tmp)					ucode_cpu_info[j].mc = NULL;			}		}		if (ucode_cpu_info[i].err == MC_IGNORED && verbose)			printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision"			       " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);	}out:	return error;}int microcode_update(XEN_GUEST_HANDLE(void) buf, unsigned long len){	int ret;	if (len != (typeof(user_buffer_size))len) {		printk(KERN_ERR "microcode: too much data\n");		return -E2BIG;	}	mutex_lock(&microcode_mutex);	user_buffer = buf.p;	user_buffer_size = len;	ret = do_microcode_update();	mutex_unlock(&microcode_mutex);	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -