···658658 earlyprintk= [X86-32,X86-64,SH,BLACKFIN]659659 earlyprintk=vga660660 earlyprintk=serial[,ttySn[,baudrate]]661661+ earlyprintk=dbgp661662662663 Append ",keep" to not disable it when the real console663664 takes over.664665665665- Only vga or serial at a time, not both.666666+ Only vga or serial or usb debug port at a time.666667667668 Currently only ttyS0 and ttyS1 are supported.668669···12311230 memmap=64K$0x1869000012321231 or12331232 memmap=0x10000$0x1869000012331233+12341234+ memory_corruption_check=0/1 [X86]12351235+ Some BIOSes seem to corrupt the first 64k of12361236+ memory when doing things like suspend/resume.12371237+ Setting this option will scan the memory12381238+ looking for corruption. Enabling this will12391239+ both detect corruption and prevent the kernel12401240+ from using the memory being corrupted.12411241+ However, its intended as a diagnostic tool; if12421242+ repeatable BIOS-originated corruption always12431243+ affects the same memory, you can use memmap=12441244+ to prevent the kernel from using that memory.12451245+12461246+ memory_corruption_check_size=size [X86]12471247+ By default it checks for corruption in the low12481248+ 64k, making this memory unavailable for normal12491249+ use. Use this parameter to scan for12501250+ corruption in more or less memory.12511251+12521252+ memory_corruption_check_period=seconds [X86]12531253+ By default it checks for corruption every 6012541254+ seconds. Use this parameter to check at some12551255+ other rate. 0 disables periodic checking.1234125612351257 memtest= [KNL,X86] Enable memtest12361258 Format: <integer>
···113113#undef NSIGSEGV114114#define NSIGSEGV 3115115116116-/*117117- * SIGTRAP si_codes118118- */119119-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */120120-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */121116#undef NSIGTRAP122117#define NSIGTRAP 4123118
-5
arch/powerpc/include/asm/siginfo.h
···15151616#include <asm-generic/siginfo.h>17171818-/*1919- * SIGTRAP si_codes2020- */2121-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */2222-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */2318#undef NSIGTRAP2419#define NSIGTRAP 42520
+81-9
arch/x86/Kconfig
···778778 Say N otherwise.779779780780config MICROCODE781781- tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"781781+ tristate "/dev/cpu/microcode - microcode support"782782 select FW_LOADER783783 ---help---784784 If you say Y here, you will be able to update the microcode on785785- Intel processors in the IA32 family, e.g. Pentium Pro, Pentium II,786786- Pentium III, Pentium 4, Xeon etc. You will obviously need the787787- actual microcode binary data itself which is not shipped with the788788- Linux kernel.785785+ certain Intel and AMD processors. The Intel support is for the786786+ IA32 family, e.g. Pentium Pro, Pentium II, Pentium III,787787+ Pentium 4, Xeon etc. The AMD support is for family 0x10 and788788+ 0x11 processors, e.g. Opteron, Phenom and Turion 64 Ultra.789789+ You will obviously need the actual microcode binary data itself790790+ which is not shipped with the Linux kernel.789791790790- For latest news and information on obtaining all the required791791- ingredients for this driver, check:792792- <http://www.urbanmyth.org/microcode/>.792792+ This option selects the general module only, you need to select793793+ at least one vendor specific module as well.793794794795 To compile this driver as a module, choose M here: the795796 module will be called microcode.796797797797-config MICROCODE_OLD_INTERFACE798798+config MICROCODE_INTEL799799+ bool "Intel microcode patch loading support"800800+ depends on MICROCODE801801+ default MICROCODE802802+ select FW_LOADER803803+ --help---804804+ This options enables microcode patch loading support for Intel805805+ processors.806806+807807+ For latest news and information on obtaining all the required808808+ Intel ingredients for this driver, check:809809+ <http://www.urbanmyth.org/microcode/>.810810+811811+config MICROCODE_AMD812812+ bool "AMD microcode patch loading support"813813+ depends on MICROCODE814814+ select FW_LOADER815815+ --help---816816+ If you select this option, microcode patch loading support for AMD817817+ processors will be enabled.818818+819819+ config MICROCODE_OLD_INTERFACE798820 def_bool y799821 depends on MICROCODE800822···10821060 For systems with a lot of RAM, this can be wasteful of precious10831061 low memory. Setting this option will put user-space page table10841062 entries in high memory.10631063+10641064+config X86_CHECK_BIOS_CORRUPTION10651065+ bool "Check for low memory corruption"10661066+ help10671067+ Periodically check for memory corruption in low memory, which10681068+ is suspected to be caused by BIOS. Even when enabled in the10691069+ configuration, it is disabled at runtime. Enable it by10701070+ setting "memory_corruption_check=1" on the kernel command10711071+ line. By default it scans the low 64k of memory every 6010721072+ seconds; see the memory_corruption_check_size and10731073+ memory_corruption_check_period parameters in10741074+ Documentation/kernel-parameters.txt to adjust this.10751075+10761076+ When enabled with the default parameters, this option has10771077+ almost no overhead, as it reserves a relatively small amount10781078+ of memory and scans it infrequently. It both detects corruption10791079+ and prevents it from affecting the running system.10801080+10811081+ It is, however, intended as a diagnostic tool; if repeatable10821082+ BIOS-originated corruption always affects the same memory,10831083+ you can use memmap= to prevent the kernel from using that10841084+ memory.10851085+10861086+config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK10871087+ bool "Set the default setting of memory_corruption_check"10881088+ depends on X86_CHECK_BIOS_CORRUPTION10891089+ default y10901090+ help10911091+ Set whether the default state of memory_corruption_check is10921092+ on or off.10931093+10941094+config X86_RESERVE_LOW_64K10951095+ bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"10961096+ default y10971097+ help10981098+ Reserve the first 64K of physical RAM on BIOSes that are known10991099+ to potentially corrupt that memory range. A numbers of BIOSes are11001100+ known to utilize this area during suspend/resume, so it must not11011101+ be used by the kernel.11021102+11031103+ Set this to N if you are absolutely sure that you trust the BIOS11041104+ to get all its memory reservations and usages right.11051105+11061106+ If you have doubts about the BIOS (e.g. suspend/resume does not11071107+ work or there's kernel crashes after certain hardware hotplug11081108+ events) and it's not AMI or Phoenix, then you might want to enable11091109+ X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical11101110+ corruption patterns.11111111+11121112+ Say Y if unsure.1085111310861114config MATH_EMULATION10871115 bool
+13
arch/x86/Kconfig.debug
···4343 with klogd/syslogd or the X server. You should normally N here,4444 unless you want to debug such a crash.45454646+config EARLY_PRINTK_DBGP4747+ bool "Early printk via EHCI debug port"4848+ default n4949+ depends on EARLY_PRINTK && PCI5050+ help5151+ Write kernel log output directly into the EHCI debug port.5252+5353+ This is useful for kernel debugging when your machine crashes very5454+ early before the console code is initialized. For normal operation5555+ it is not recommended because it looks ugly and doesn't cooperate5656+ with klogd/syslogd or the X server. You should normally N here,5757+ unless you want to debug such a crash. You need usb debug device.5858+4659config DEBUG_STACKOVERFLOW4760 bool "Check for stack overflows"4861 depends on DEBUG_KERNEL
+5
arch/x86/Makefile_32.cpu
···4545# cpu entries4646cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686))47474848+# Bug fix for binutils: this option is required in order to keep4949+# binutils from generating NOPL instructions against our will.5050+ifneq ($(CONFIG_X86_P6_NOP),y)5151+cflags-y += $(call cc-option,-Wa$(comma)-mtune=generic32,)5252+endif
···224224static void vesa_store_mode_params_graphics(void)225225{226226 /* Tell the kernel we're in VESA graphics mode */227227- boot_params.screen_info.orig_video_isVGA = 0x23;227227+ boot_params.screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB;228228229229 /* Mode parameters */230230 boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
-1
arch/x86/configs/i386_defconfig
···15351535CONFIG_VGA_CONSOLE=y15361536CONFIG_VGACON_SOFT_SCROLLBACK=y15371537CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=6415381538-CONFIG_VIDEO_SELECT=y15391538CONFIG_DUMMY_CONSOLE=y15401539# CONFIG_FRAMEBUFFER_CONSOLE is not set15411540CONFIG_LOGO=y
-1
arch/x86/configs/x86_64_defconfig
···15051505CONFIG_VGA_CONSOLE=y15061506CONFIG_VGACON_SOFT_SCROLLBACK=y15071507CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=6415081508-CONFIG_VIDEO_SELECT=y15091508CONFIG_DUMMY_CONSOLE=y15101509# CONFIG_FRAMEBUFFER_CONSOLE is not set15111510CONFIG_LOGO=y
···95959696}97979898+static u32 ati_ixp4x0_rev(int num, int slot, int func)9999+{100100+ u32 d;101101+ u8 b;102102+103103+ b = read_pci_config_byte(num, slot, func, 0xac);104104+ b &= ~(1<<5);105105+ write_pci_config_byte(num, slot, func, 0xac, b);106106+107107+ d = read_pci_config(num, slot, func, 0x70);108108+ d |= 1<<8;109109+ write_pci_config(num, slot, func, 0x70, d);110110+111111+ d = read_pci_config(num, slot, func, 0x8);112112+ d &= 0xff;113113+ return d;114114+}115115+116116+static void __init ati_bugs(int num, int slot, int func)117117+{118118+#if defined(CONFIG_ACPI) && defined (CONFIG_X86_IO_APIC)119119+ u32 d;120120+ u8 b;121121+122122+ if (acpi_use_timer_override)123123+ return;124124+125125+ d = ati_ixp4x0_rev(num, slot, func);126126+ if (d < 0x82)127127+ acpi_skip_timer_override = 1;128128+ else {129129+ /* check for IRQ0 interrupt swap */130130+ outb(0x72, 0xcd6); b = inb(0xcd7);131131+ if (!(b & 0x2))132132+ acpi_skip_timer_override = 1;133133+ }134134+135135+ if (acpi_skip_timer_override) {136136+ printk(KERN_INFO "SB4X0 revision 0x%x\n", d);137137+ printk(KERN_INFO "Ignoring ACPI timer override.\n");138138+ printk(KERN_INFO "If you got timer trouble "139139+ "try acpi_use_timer_override\n");140140+ }141141+#endif142142+}143143+98144#ifdef CONFIG_DMAR99145static void __init intel_g33_dmar(int num, int slot, int func)100146{···174128 PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, via_bugs },175129 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,176130 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },131131+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,132132+ PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },177133#ifdef CONFIG_DMAR178134 { PCI_VENDOR_ID_INTEL, 0x29c0,179135 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, intel_g33_dmar },
+743-5
arch/x86/kernel/early_printk.c
···33#include <linux/init.h>44#include <linux/string.h>55#include <linux/screen_info.h>66+#include <linux/usb/ch9.h>77+#include <linux/pci_regs.h>88+#include <linux/pci_ids.h>99+#include <linux/errno.h>610#include <asm/io.h>711#include <asm/processor.h>812#include <asm/fcntl.h>913#include <asm/setup.h>1014#include <xen/hvc-console.h>1515+#include <asm/pci-direct.h>1616+#include <asm/pgtable.h>1717+#include <asm/fixmap.h>1818+#include <linux/usb/ehci_def.h>11191220/* Simple VGA output */1321#define VGABASE (__ISA_IO_base + 0xb8000)···8678static int early_serial_putc(unsigned char ch)8779{8880 unsigned timeout = 0xffff;8181+8982 while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)9083 cpu_relax();9184 outb(ch, early_serial_base + TXR);···120111 if (!strncmp(s, "0x", 2)) {121112 early_serial_base = simple_strtoul(s, &e, 16);122113 } else {123123- static int bases[] = { 0x3f8, 0x2f8 };114114+ static const int __initconst bases[] = { 0x3f8, 0x2f8 };124115125116 if (!strncmp(s, "ttyS", 4))126117 s += 4;···160151 .index = -1,161152};162153154154+#ifdef CONFIG_EARLY_PRINTK_DBGP155155+156156+static struct ehci_caps __iomem *ehci_caps;157157+static struct ehci_regs __iomem *ehci_regs;158158+static struct ehci_dbg_port __iomem *ehci_debug;159159+static unsigned int dbgp_endpoint_out;160160+161161+struct ehci_dev {162162+ u32 bus;163163+ u32 slot;164164+ u32 func;165165+};166166+167167+static struct ehci_dev ehci_dev;168168+169169+#define USB_DEBUG_DEVNUM 127170170+171171+#define DBGP_DATA_TOGGLE 0x8800172172+173173+static inline u32 dbgp_pid_update(u32 x, u32 tok)174174+{175175+ return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff);176176+}177177+178178+static inline u32 dbgp_len_update(u32 x, u32 len)179179+{180180+ return (x & ~0x0f) | (len & 0x0f);181181+}182182+183183+/*184184+ * USB Packet IDs (PIDs)185185+ */186186+187187+/* token */188188+#define USB_PID_OUT 0xe1189189+#define USB_PID_IN 0x69190190+#define USB_PID_SOF 0xa5191191+#define USB_PID_SETUP 0x2d192192+/* handshake */193193+#define USB_PID_ACK 0xd2194194+#define USB_PID_NAK 0x5a195195+#define USB_PID_STALL 0x1e196196+#define USB_PID_NYET 0x96197197+/* data */198198+#define USB_PID_DATA0 0xc3199199+#define USB_PID_DATA1 0x4b200200+#define USB_PID_DATA2 0x87201201+#define USB_PID_MDATA 0x0f202202+/* Special */203203+#define USB_PID_PREAMBLE 0x3c204204+#define USB_PID_ERR 0x3c205205+#define USB_PID_SPLIT 0x78206206+#define USB_PID_PING 0xb4207207+#define USB_PID_UNDEF_0 0xf0208208+209209+#define USB_PID_DATA_TOGGLE 0x88210210+#define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)211211+212212+#define PCI_CAP_ID_EHCI_DEBUG 0xa213213+214214+#define HUB_ROOT_RESET_TIME 50 /* times are in msec */215215+#define HUB_SHORT_RESET_TIME 10216216+#define HUB_LONG_RESET_TIME 200217217+#define HUB_RESET_TIMEOUT 500218218+219219+#define DBGP_MAX_PACKET 8220220+221221+static int dbgp_wait_until_complete(void)222222+{223223+ u32 ctrl;224224+ int loop = 0x100000;225225+226226+ do {227227+ ctrl = readl(&ehci_debug->control);228228+ /* Stop when the transaction is finished */229229+ if (ctrl & DBGP_DONE)230230+ break;231231+ } while (--loop > 0);232232+233233+ if (!loop)234234+ return -1;235235+236236+ /*237237+ * Now that we have observed the completed transaction,238238+ * clear the done bit.239239+ */240240+ writel(ctrl | DBGP_DONE, &ehci_debug->control);241241+ return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);242242+}243243+244244+static void dbgp_mdelay(int ms)245245+{246246+ int i;247247+248248+ while (ms--) {249249+ for (i = 0; i < 1000; i++)250250+ outb(0x1, 0x80);251251+ }252252+}253253+254254+static void dbgp_breath(void)255255+{256256+ /* Sleep to give the debug port a chance to breathe */257257+}258258+259259+static int dbgp_wait_until_done(unsigned ctrl)260260+{261261+ u32 pids, lpid;262262+ int ret;263263+ int loop = 3;264264+265265+retry:266266+ writel(ctrl | DBGP_GO, &ehci_debug->control);267267+ ret = dbgp_wait_until_complete();268268+ pids = readl(&ehci_debug->pids);269269+ lpid = DBGP_PID_GET(pids);270270+271271+ if (ret < 0)272272+ return ret;273273+274274+ /*275275+ * If the port is getting full or it has dropped data276276+ * start pacing ourselves, not necessary but it's friendly.277277+ */278278+ if ((lpid == USB_PID_NAK) || (lpid == USB_PID_NYET))279279+ dbgp_breath();280280+281281+ /* If I get a NACK reissue the transmission */282282+ if (lpid == USB_PID_NAK) {283283+ if (--loop > 0)284284+ goto retry;285285+ }286286+287287+ return ret;288288+}289289+290290+static void dbgp_set_data(const void *buf, int size)291291+{292292+ const unsigned char *bytes = buf;293293+ u32 lo, hi;294294+ int i;295295+296296+ lo = hi = 0;297297+ for (i = 0; i < 4 && i < size; i++)298298+ lo |= bytes[i] << (8*i);299299+ for (; i < 8 && i < size; i++)300300+ hi |= bytes[i] << (8*(i - 4));301301+ writel(lo, &ehci_debug->data03);302302+ writel(hi, &ehci_debug->data47);303303+}304304+305305+static void dbgp_get_data(void *buf, int size)306306+{307307+ unsigned char *bytes = buf;308308+ u32 lo, hi;309309+ int i;310310+311311+ lo = readl(&ehci_debug->data03);312312+ hi = readl(&ehci_debug->data47);313313+ for (i = 0; i < 4 && i < size; i++)314314+ bytes[i] = (lo >> (8*i)) & 0xff;315315+ for (; i < 8 && i < size; i++)316316+ bytes[i] = (hi >> (8*(i - 4))) & 0xff;317317+}318318+319319+static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,320320+ const char *bytes, int size)321321+{322322+ u32 pids, addr, ctrl;323323+ int ret;324324+325325+ if (size > DBGP_MAX_PACKET)326326+ return -1;327327+328328+ addr = DBGP_EPADDR(devnum, endpoint);329329+330330+ pids = readl(&ehci_debug->pids);331331+ pids = dbgp_pid_update(pids, USB_PID_OUT);332332+333333+ ctrl = readl(&ehci_debug->control);334334+ ctrl = dbgp_len_update(ctrl, size);335335+ ctrl |= DBGP_OUT;336336+ ctrl |= DBGP_GO;337337+338338+ dbgp_set_data(bytes, size);339339+ writel(addr, &ehci_debug->address);340340+ writel(pids, &ehci_debug->pids);341341+342342+ ret = dbgp_wait_until_done(ctrl);343343+ if (ret < 0)344344+ return ret;345345+346346+ return ret;347347+}348348+349349+static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,350350+ int size)351351+{352352+ u32 pids, addr, ctrl;353353+ int ret;354354+355355+ if (size > DBGP_MAX_PACKET)356356+ return -1;357357+358358+ addr = DBGP_EPADDR(devnum, endpoint);359359+360360+ pids = readl(&ehci_debug->pids);361361+ pids = dbgp_pid_update(pids, USB_PID_IN);362362+363363+ ctrl = readl(&ehci_debug->control);364364+ ctrl = dbgp_len_update(ctrl, size);365365+ ctrl &= ~DBGP_OUT;366366+ ctrl |= DBGP_GO;367367+368368+ writel(addr, &ehci_debug->address);369369+ writel(pids, &ehci_debug->pids);370370+ ret = dbgp_wait_until_done(ctrl);371371+ if (ret < 0)372372+ return ret;373373+374374+ if (size > ret)375375+ size = ret;376376+ dbgp_get_data(data, size);377377+ return ret;378378+}379379+380380+static int dbgp_control_msg(unsigned devnum, int requesttype, int request,381381+ int value, int index, void *data, int size)382382+{383383+ u32 pids, addr, ctrl;384384+ struct usb_ctrlrequest req;385385+ int read;386386+ int ret;387387+388388+ read = (requesttype & USB_DIR_IN) != 0;389389+ if (size > (read ? DBGP_MAX_PACKET:0))390390+ return -1;391391+392392+ /* Compute the control message */393393+ req.bRequestType = requesttype;394394+ req.bRequest = request;395395+ req.wValue = cpu_to_le16(value);396396+ req.wIndex = cpu_to_le16(index);397397+ req.wLength = cpu_to_le16(size);398398+399399+ pids = DBGP_PID_SET(USB_PID_DATA0, USB_PID_SETUP);400400+ addr = DBGP_EPADDR(devnum, 0);401401+402402+ ctrl = readl(&ehci_debug->control);403403+ ctrl = dbgp_len_update(ctrl, sizeof(req));404404+ ctrl |= DBGP_OUT;405405+ ctrl |= DBGP_GO;406406+407407+ /* Send the setup message */408408+ dbgp_set_data(&req, sizeof(req));409409+ writel(addr, &ehci_debug->address);410410+ writel(pids, &ehci_debug->pids);411411+ ret = dbgp_wait_until_done(ctrl);412412+ if (ret < 0)413413+ return ret;414414+415415+ /* Read the result */416416+ return dbgp_bulk_read(devnum, 0, data, size);417417+}418418+419419+420420+/* Find a PCI capability */421421+static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap)422422+{423423+ u8 pos;424424+ int bytes;425425+426426+ if (!(read_pci_config_16(num, slot, func, PCI_STATUS) &427427+ PCI_STATUS_CAP_LIST))428428+ return 0;429429+430430+ pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST);431431+ for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {432432+ u8 id;433433+434434+ pos &= ~3;435435+ id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID);436436+ if (id == 0xff)437437+ break;438438+ if (id == cap)439439+ return pos;440440+441441+ pos = read_pci_config_byte(num, slot, func,442442+ pos+PCI_CAP_LIST_NEXT);443443+ }444444+ return 0;445445+}446446+447447+static u32 __init __find_dbgp(u32 bus, u32 slot, u32 func)448448+{449449+ u32 class;450450+451451+ class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);452452+ if ((class >> 8) != PCI_CLASS_SERIAL_USB_EHCI)453453+ return 0;454454+455455+ return find_cap(bus, slot, func, PCI_CAP_ID_EHCI_DEBUG);456456+}457457+458458+static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc)459459+{460460+ u32 bus, slot, func;461461+462462+ for (bus = 0; bus < 256; bus++) {463463+ for (slot = 0; slot < 32; slot++) {464464+ for (func = 0; func < 8; func++) {465465+ unsigned cap;466466+467467+ cap = __find_dbgp(bus, slot, func);468468+469469+ if (!cap)470470+ continue;471471+ if (ehci_num-- != 0)472472+ continue;473473+ *rbus = bus;474474+ *rslot = slot;475475+ *rfunc = func;476476+ return cap;477477+ }478478+ }479479+ }480480+ return 0;481481+}482482+483483+static int ehci_reset_port(int port)484484+{485485+ u32 portsc;486486+ u32 delay_time, delay;487487+ int loop;488488+489489+ /* Reset the usb debug port */490490+ portsc = readl(&ehci_regs->port_status[port - 1]);491491+ portsc &= ~PORT_PE;492492+ portsc |= PORT_RESET;493493+ writel(portsc, &ehci_regs->port_status[port - 1]);494494+495495+ delay = HUB_ROOT_RESET_TIME;496496+ for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT;497497+ delay_time += delay) {498498+ dbgp_mdelay(delay);499499+500500+ portsc = readl(&ehci_regs->port_status[port - 1]);501501+ if (portsc & PORT_RESET) {502502+ /* force reset to complete */503503+ loop = 2;504504+ writel(portsc & ~(PORT_RWC_BITS | PORT_RESET),505505+ &ehci_regs->port_status[port - 1]);506506+ do {507507+ portsc = readl(&ehci_regs->port_status[port-1]);508508+ } while ((portsc & PORT_RESET) && (--loop > 0));509509+ }510510+511511+ /* Device went away? */512512+ if (!(portsc & PORT_CONNECT))513513+ return -ENOTCONN;514514+515515+ /* bomb out completely if something weird happend */516516+ if ((portsc & PORT_CSC))517517+ return -EINVAL;518518+519519+ /* If we've finished resetting, then break out of the loop */520520+ if (!(portsc & PORT_RESET) && (portsc & PORT_PE))521521+ return 0;522522+ }523523+ return -EBUSY;524524+}525525+526526+static int ehci_wait_for_port(int port)527527+{528528+ u32 status;529529+ int ret, reps;530530+531531+ for (reps = 0; reps < 3; reps++) {532532+ dbgp_mdelay(100);533533+ status = readl(&ehci_regs->status);534534+ if (status & STS_PCD) {535535+ ret = ehci_reset_port(port);536536+ if (ret == 0)537537+ return 0;538538+ }539539+ }540540+ return -ENOTCONN;541541+}542542+543543+#ifdef DBGP_DEBUG544544+# define dbgp_printk early_printk545545+#else546546+static inline void dbgp_printk(const char *fmt, ...) { }547547+#endif548548+549549+typedef void (*set_debug_port_t)(int port);550550+551551+static void default_set_debug_port(int port)552552+{553553+}554554+555555+static set_debug_port_t set_debug_port = default_set_debug_port;556556+557557+static void nvidia_set_debug_port(int port)558558+{559559+ u32 dword;560560+ dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,561561+ 0x74);562562+ dword &= ~(0x0f<<12);563563+ dword |= ((port & 0x0f)<<12);564564+ write_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func, 0x74,565565+ dword);566566+ dbgp_printk("set debug port to %d\n", port);567567+}568568+569569+static void __init detect_set_debug_port(void)570570+{571571+ u32 vendorid;572572+573573+ vendorid = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,574574+ 0x00);575575+576576+ if ((vendorid & 0xffff) == 0x10de) {577577+ dbgp_printk("using nvidia set_debug_port\n");578578+ set_debug_port = nvidia_set_debug_port;579579+ }580580+}581581+582582+static int __init ehci_setup(void)583583+{584584+ struct usb_debug_descriptor dbgp_desc;585585+ u32 cmd, ctrl, status, portsc, hcs_params;586586+ u32 debug_port, new_debug_port = 0, n_ports;587587+ u32 devnum;588588+ int ret, i;589589+ int loop;590590+ int port_map_tried;591591+ int playtimes = 3;592592+593593+try_next_time:594594+ port_map_tried = 0;595595+596596+try_next_port:597597+598598+ hcs_params = readl(&ehci_caps->hcs_params);599599+ debug_port = HCS_DEBUG_PORT(hcs_params);600600+ n_ports = HCS_N_PORTS(hcs_params);601601+602602+ dbgp_printk("debug_port: %d\n", debug_port);603603+ dbgp_printk("n_ports: %d\n", n_ports);604604+605605+ for (i = 1; i <= n_ports; i++) {606606+ portsc = readl(&ehci_regs->port_status[i-1]);607607+ dbgp_printk("portstatus%d: %08x\n", i, portsc);608608+ }609609+610610+ if (port_map_tried && (new_debug_port != debug_port)) {611611+ if (--playtimes) {612612+ set_debug_port(new_debug_port);613613+ goto try_next_time;614614+ }615615+ return -1;616616+ }617617+618618+ loop = 10;619619+ /* Reset the EHCI controller */620620+ cmd = readl(&ehci_regs->command);621621+ cmd |= CMD_RESET;622622+ writel(cmd, &ehci_regs->command);623623+ do {624624+ cmd = readl(&ehci_regs->command);625625+ } while ((cmd & CMD_RESET) && (--loop > 0));626626+627627+ if (!loop) {628628+ dbgp_printk("can not reset ehci\n");629629+ return -1;630630+ }631631+ dbgp_printk("ehci reset done\n");632632+633633+ /* Claim ownership, but do not enable yet */634634+ ctrl = readl(&ehci_debug->control);635635+ ctrl |= DBGP_OWNER;636636+ ctrl &= ~(DBGP_ENABLED | DBGP_INUSE);637637+ writel(ctrl, &ehci_debug->control);638638+639639+ /* Start the ehci running */640640+ cmd = readl(&ehci_regs->command);641641+ cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET);642642+ cmd |= CMD_RUN;643643+ writel(cmd, &ehci_regs->command);644644+645645+ /* Ensure everything is routed to the EHCI */646646+ writel(FLAG_CF, &ehci_regs->configured_flag);647647+648648+ /* Wait until the controller is no longer halted */649649+ loop = 10;650650+ do {651651+ status = readl(&ehci_regs->status);652652+ } while ((status & STS_HALT) && (--loop > 0));653653+654654+ if (!loop) {655655+ dbgp_printk("ehci can be started\n");656656+ return -1;657657+ }658658+ dbgp_printk("ehci started\n");659659+660660+ /* Wait for a device to show up in the debug port */661661+ ret = ehci_wait_for_port(debug_port);662662+ if (ret < 0) {663663+ dbgp_printk("No device found in debug port\n");664664+ goto next_debug_port;665665+ }666666+ dbgp_printk("ehci wait for port done\n");667667+668668+ /* Enable the debug port */669669+ ctrl = readl(&ehci_debug->control);670670+ ctrl |= DBGP_CLAIM;671671+ writel(ctrl, &ehci_debug->control);672672+ ctrl = readl(&ehci_debug->control);673673+ if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) {674674+ dbgp_printk("No device in debug port\n");675675+ writel(ctrl & ~DBGP_CLAIM, &ehci_debug->control);676676+ goto err;677677+ }678678+ dbgp_printk("debug ported enabled\n");679679+680680+ /* Completely transfer the debug device to the debug controller */681681+ portsc = readl(&ehci_regs->port_status[debug_port - 1]);682682+ portsc &= ~PORT_PE;683683+ writel(portsc, &ehci_regs->port_status[debug_port - 1]);684684+685685+ dbgp_mdelay(100);686686+687687+ /* Find the debug device and make it device number 127 */688688+ for (devnum = 0; devnum <= 127; devnum++) {689689+ ret = dbgp_control_msg(devnum,690690+ USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,691691+ USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,692692+ &dbgp_desc, sizeof(dbgp_desc));693693+ if (ret > 0)694694+ break;695695+ }696696+ if (devnum > 127) {697697+ dbgp_printk("Could not find attached debug device\n");698698+ goto err;699699+ }700700+ if (ret < 0) {701701+ dbgp_printk("Attached device is not a debug device\n");702702+ goto err;703703+ }704704+ dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;705705+706706+ /* Move the device to 127 if it isn't already there */707707+ if (devnum != USB_DEBUG_DEVNUM) {708708+ ret = dbgp_control_msg(devnum,709709+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,710710+ USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);711711+ if (ret < 0) {712712+ dbgp_printk("Could not move attached device to %d\n",713713+ USB_DEBUG_DEVNUM);714714+ goto err;715715+ }716716+ devnum = USB_DEBUG_DEVNUM;717717+ dbgp_printk("debug device renamed to 127\n");718718+ }719719+720720+ /* Enable the debug interface */721721+ ret = dbgp_control_msg(USB_DEBUG_DEVNUM,722722+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,723723+ USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0);724724+ if (ret < 0) {725725+ dbgp_printk(" Could not enable the debug device\n");726726+ goto err;727727+ }728728+ dbgp_printk("debug interface enabled\n");729729+730730+ /* Perform a small write to get the even/odd data state in sync731731+ */732732+ ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, dbgp_endpoint_out, " ", 1);733733+ if (ret < 0) {734734+ dbgp_printk("dbgp_bulk_write failed: %d\n", ret);735735+ goto err;736736+ }737737+ dbgp_printk("small write doned\n");738738+739739+ return 0;740740+err:741741+ /* Things didn't work so remove my claim */742742+ ctrl = readl(&ehci_debug->control);743743+ ctrl &= ~(DBGP_CLAIM | DBGP_OUT);744744+ writel(ctrl, &ehci_debug->control);745745+ return -1;746746+747747+next_debug_port:748748+ port_map_tried |= (1<<(debug_port - 1));749749+ new_debug_port = ((debug_port-1+1)%n_ports) + 1;750750+ if (port_map_tried != ((1<<n_ports) - 1)) {751751+ set_debug_port(new_debug_port);752752+ goto try_next_port;753753+ }754754+ if (--playtimes) {755755+ set_debug_port(new_debug_port);756756+ goto try_next_time;757757+ }758758+759759+ return -1;760760+}761761+762762+static int __init early_dbgp_init(char *s)763763+{764764+ u32 debug_port, bar, offset;765765+ u32 bus, slot, func, cap;766766+ void __iomem *ehci_bar;767767+ u32 dbgp_num;768768+ u32 bar_val;769769+ char *e;770770+ int ret;771771+ u8 byte;772772+773773+ if (!early_pci_allowed())774774+ return -1;775775+776776+ dbgp_num = 0;777777+ if (*s)778778+ dbgp_num = simple_strtoul(s, &e, 10);779779+ dbgp_printk("dbgp_num: %d\n", dbgp_num);780780+781781+ cap = find_dbgp(dbgp_num, &bus, &slot, &func);782782+ if (!cap)783783+ return -1;784784+785785+ dbgp_printk("Found EHCI debug port on %02x:%02x.%1x\n", bus, slot,786786+ func);787787+788788+ debug_port = read_pci_config(bus, slot, func, cap);789789+ bar = (debug_port >> 29) & 0x7;790790+ bar = (bar * 4) + 0xc;791791+ offset = (debug_port >> 16) & 0xfff;792792+ dbgp_printk("bar: %02x offset: %03x\n", bar, offset);793793+ if (bar != PCI_BASE_ADDRESS_0) {794794+ dbgp_printk("only debug ports on bar 1 handled.\n");795795+796796+ return -1;797797+ }798798+799799+ bar_val = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);800800+ dbgp_printk("bar_val: %02x offset: %03x\n", bar_val, offset);801801+ if (bar_val & ~PCI_BASE_ADDRESS_MEM_MASK) {802802+ dbgp_printk("only simple 32bit mmio bars supported\n");803803+804804+ return -1;805805+ }806806+807807+ /* double check if the mem space is enabled */808808+ byte = read_pci_config_byte(bus, slot, func, 0x04);809809+ if (!(byte & 0x2)) {810810+ byte |= 0x02;811811+ write_pci_config_byte(bus, slot, func, 0x04, byte);812812+ dbgp_printk("mmio for ehci enabled\n");813813+ }814814+815815+ /*816816+ * FIXME I don't have the bar size so just guess PAGE_SIZE is more817817+ * than enough. 1K is the biggest I have seen.818818+ */819819+ set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK);820820+ ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE);821821+ ehci_bar += bar_val & ~PAGE_MASK;822822+ dbgp_printk("ehci_bar: %p\n", ehci_bar);823823+824824+ ehci_caps = ehci_bar;825825+ ehci_regs = ehci_bar + HC_LENGTH(readl(&ehci_caps->hc_capbase));826826+ ehci_debug = ehci_bar + offset;827827+ ehci_dev.bus = bus;828828+ ehci_dev.slot = slot;829829+ ehci_dev.func = func;830830+831831+ detect_set_debug_port();832832+833833+ ret = ehci_setup();834834+ if (ret < 0) {835835+ dbgp_printk("ehci_setup failed\n");836836+ ehci_debug = NULL;837837+838838+ return -1;839839+ }840840+841841+ return 0;842842+}843843+844844+static void early_dbgp_write(struct console *con, const char *str, u32 n)845845+{846846+ int chunk, ret;847847+848848+ if (!ehci_debug)849849+ return;850850+ while (n > 0) {851851+ chunk = n;852852+ if (chunk > DBGP_MAX_PACKET)853853+ chunk = DBGP_MAX_PACKET;854854+ ret = dbgp_bulk_write(USB_DEBUG_DEVNUM,855855+ dbgp_endpoint_out, str, chunk);856856+ str += chunk;857857+ n -= chunk;858858+ }859859+}860860+861861+static struct console early_dbgp_console = {862862+ .name = "earlydbg",863863+ .write = early_dbgp_write,864864+ .flags = CON_PRINTBUFFER,865865+ .index = -1,866866+};867867+#endif868868+163869/* Console interface to a host file on AMD's SimNow! */164870165871static int simnow_fd;···889165static noinline long simnow(long cmd, long a, long b, long c)890166{891167 long ret;168168+892169 asm volatile("cpuid" :893170 "=a" (ret) :894171 "b" (a), "c" (b), "d" (c), "0" (MAGIC1), "D" (cmd + MAGIC2));···899174static void __init simnow_init(char *str)900175{901176 char *fn = "klog";177177+902178 if (*str == '=')903179 fn = ++str;904180 /* error ignored */···920194921195/* Direct interface for emergencies */922196static struct console *early_console = &early_vga_console;923923-static int early_console_initialized;197197+static int __initdata early_console_initialized;924198925199asmlinkage void early_printk(const char *fmt, ...)926200{···934208 va_end(ap);935209}936210937937-static int __initdata keep_early;938211939212static int __init setup_early_printk(char *buf)940213{214214+ int keep_early;215215+941216 if (!buf)942217 return 0;943218···946219 return 0;947220 early_console_initialized = 1;948221949949- if (strstr(buf, "keep"))950950- keep_early = 1;222222+ keep_early = (strstr(buf, "keep") != NULL);951223952224 if (!strncmp(buf, "serial", 6)) {953225 early_serial_init(buf + 6);···964238 simnow_init(buf + 6);965239 early_console = &simnow_console;966240 keep_early = 1;241241+#ifdef CONFIG_EARLY_PRINTK_DBGP242242+ } else if (!strncmp(buf, "dbgp", 4)) {243243+ if (early_dbgp_init(buf+4) < 0)244244+ return 0;245245+ early_console = &early_dbgp_console;246246+ /*247247+ * usb subsys will reset ehci controller, so don't keep248248+ * that early console249249+ */250250+ keep_early = 0;251251+#endif967252#ifdef CONFIG_HVC_XEN968253 } else if (!strncmp(buf, "xen", 3)) {969254 early_console = &xenboot_console;···988251 register_console(early_console);989252 return 0;990253}254254+991255early_param("earlyprintk", setup_early_printk);
+14
arch/x86/kernel/i387.c
···468468469469static int save_i387_xsave(void __user *buf)470470{471471+ struct task_struct *tsk = current;471472 struct _fpstate_ia32 __user *fx = buf;472473 int err = 0;474474+475475+ /*476476+ * For legacy compatible, we always set FP/SSE bits in the bit477477+ * vector while saving the state to the user context.478478+ * This will enable us capturing any changes(during sigreturn) to479479+ * the FP/SSE bits by the legacy applications which don't touch480480+ * xstate_bv in the xsave header.481481+ *482482+ * xsave aware applications can change the xstate_bv in the xsave483483+ * header as well as change any contents in the memory layout.484484+ * xrestore as part of sigreturn will capture all the changes.485485+ */486486+ tsk->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;473487474488 if (save_i387_fxsave(fx) < 0)475489 return -1;
+8-1
arch/x86/kernel/ldt.c
···5252 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,5353 (mincount - oldsize) * LDT_ENTRY_SIZE);54545555+ paravirt_alloc_ldt(newldt, mincount);5656+5557#ifdef CONFIG_X86_645658 /* CHECKME: Do we really need this ? */5759 wmb();···7674#endif7775 }7876 if (oldsize) {7777+ paravirt_free_ldt(oldldt, oldsize);7978 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)8079 vfree(oldldt);8180 else···8885static inline int copy_ldt(mm_context_t *new, mm_context_t *old)8986{9087 int err = alloc_ldt(new, old->size, 0);8888+ int i;91899290 if (err < 0)9391 return err;9494- memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE);9292+9393+ for(i = 0; i < old->size; i++)9494+ write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);9595 return 0;9696}9797···131125 if (mm == current->active_mm)132126 clear_LDT();133127#endif128128+ paravirt_free_ldt(mm->context.ldt, mm->context.size);134129 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)135130 vfree(mm->context.ldt);136131 else
-853
arch/x86/kernel/microcode.c
···11-/*22- * Intel CPU Microcode Update Driver for Linux33- *44- * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>55- * 2006 Shaohua Li <shaohua.li@intel.com>66- *77- * This driver allows to upgrade microcode on Intel processors88- * belonging to IA-32 family - PentiumPro, Pentium II,99- * Pentium III, Xeon, Pentium 4, etc.1010- *1111- * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture1212- * Software Developer's Manual1313- * Order Number 253668 or free download from:1414- *1515- * http://developer.intel.com/design/pentium4/manuals/253668.htm1616- *1717- * For more information, go to http://www.urbanmyth.org/microcode1818- *1919- * This program is free software; you can redistribute it and/or2020- * modify it under the terms of the GNU General Public License2121- * as published by the Free Software Foundation; either version2222- * 2 of the License, or (at your option) any later version.2323- *2424- * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>2525- * Initial release.2626- * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>2727- * Added read() support + cleanups.2828- * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>2929- * Added 'device trimming' support. open(O_WRONLY) zeroes3030- * and frees the saved copy of applied microcode.3131- * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>3232- * Made to use devfs (/dev/cpu/microcode) + cleanups.3333- * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>3434- * Added misc device support (now uses both devfs and misc).3535- * Added MICROCODE_IOCFREE ioctl to clear memory.3636- * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>3737- * Messages for error cases (non Intel & no suitable microcode).3838- * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>3939- * Removed ->release(). Removed exclusive open and status bitmap.4040- * Added microcode_rwsem to serialize read()/write()/ioctl().4141- * Removed global kernel lock usage.4242- * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>4343- * Write 0 to 0x8B msr and then cpuid before reading revision,4444- * so that it works even if there were no update done by the4545- * BIOS. Otherwise, reading from 0x8B gives junk (which happened4646- * to be 0 on my machine which is why it worked even when I4747- * disabled update by the BIOS)4848- * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.4949- * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and5050- * Tigran Aivazian <tigran@veritas.com>5151- * Intel Pentium 4 processor support and bugfixes.5252- * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>5353- * Bugfix for HT (Hyper-Threading) enabled processors5454- * whereby processor resources are shared by all logical processors5555- * in a single CPU package.5656- * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and5757- * Tigran Aivazian <tigran@veritas.com>,5858- * Serialize updates as required on HT processors due to speculative5959- * nature of implementation.6060- * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>6161- * Fix the panic when writing zero-length microcode chunk.6262- * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,6363- * Jun Nakajima <jun.nakajima@intel.com>6464- * Support for the microcode updates in the new format.6565- * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>6666- * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl6767- * because we no longer hold a copy of applied microcode6868- * in kernel memory.6969- * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>7070- * Fix sigmatch() macro to handle old CPUs with pf == 0.7171- * Thanks to Stuart Swales for pointing out this bug.7272- */7373-7474-//#define DEBUG /* pr_debug */7575-#include <linux/capability.h>7676-#include <linux/kernel.h>7777-#include <linux/init.h>7878-#include <linux/sched.h>7979-#include <linux/smp_lock.h>8080-#include <linux/cpumask.h>8181-#include <linux/module.h>8282-#include <linux/slab.h>8383-#include <linux/vmalloc.h>8484-#include <linux/miscdevice.h>8585-#include <linux/spinlock.h>8686-#include <linux/mm.h>8787-#include <linux/fs.h>8888-#include <linux/mutex.h>8989-#include <linux/cpu.h>9090-#include <linux/firmware.h>9191-#include <linux/platform_device.h>9292-9393-#include <asm/msr.h>9494-#include <asm/uaccess.h>9595-#include <asm/processor.h>9696-9797-MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");9898-MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");9999-MODULE_LICENSE("GPL");100100-101101-#define MICROCODE_VERSION "1.14a"102102-103103-#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */104104-#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */105105-#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */106106-#define EXT_HEADER_SIZE (sizeof (struct extended_sigtable)) /* 20 bytes */107107-#define EXT_SIGNATURE_SIZE (sizeof (struct extended_signature)) /* 12 bytes */108108-#define DWSIZE (sizeof (u32))109109-#define get_totalsize(mc) \110110- (((microcode_t *)mc)->hdr.totalsize ? \111111- ((microcode_t *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE)112112-#define get_datasize(mc) \113113- (((microcode_t *)mc)->hdr.datasize ? \114114- ((microcode_t *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)115115-116116-#define sigmatch(s1, s2, p1, p2) \117117- (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))118118-119119-#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)120120-121121-/* serialize access to the physical write to MSR 0x79 */122122-static DEFINE_SPINLOCK(microcode_update_lock);123123-124124-/* no concurrent ->write()s are allowed on /dev/cpu/microcode */125125-static DEFINE_MUTEX(microcode_mutex);126126-127127-static struct ucode_cpu_info {128128- int valid;129129- unsigned int sig;130130- unsigned int pf;131131- unsigned int rev;132132- microcode_t *mc;133133-} ucode_cpu_info[NR_CPUS];134134-135135-static void collect_cpu_info(int cpu_num)136136-{137137- struct cpuinfo_x86 *c = &cpu_data(cpu_num);138138- struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;139139- unsigned int val[2];140140-141141- /* We should bind the task to the CPU */142142- BUG_ON(raw_smp_processor_id() != cpu_num);143143- uci->pf = uci->rev = 0;144144- uci->mc = NULL;145145- uci->valid = 1;146146-147147- if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||148148- cpu_has(c, X86_FEATURE_IA64)) {149149- printk(KERN_ERR "microcode: CPU%d not a capable Intel "150150- "processor\n", cpu_num);151151- uci->valid = 0;152152- return;153153- }154154-155155- uci->sig = cpuid_eax(0x00000001);156156-157157- if ((c->x86_model >= 5) || (c->x86 > 6)) {158158- /* get processor flags from MSR 0x17 */159159- rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);160160- uci->pf = 1 << ((val[1] >> 18) & 7);161161- }162162-163163- wrmsr(MSR_IA32_UCODE_REV, 0, 0);164164- /* see notes above for revision 1.07. Apparent chip bug */165165- sync_core();166166- /* get the current revision from MSR 0x8B */167167- rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev);168168- pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",169169- uci->sig, uci->pf, uci->rev);170170-}171171-172172-static inline int microcode_update_match(int cpu_num,173173- microcode_header_t *mc_header, int sig, int pf)174174-{175175- struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;176176-177177- if (!sigmatch(sig, uci->sig, pf, uci->pf)178178- || mc_header->rev <= uci->rev)179179- return 0;180180- return 1;181181-}182182-183183-static int microcode_sanity_check(void *mc)184184-{185185- microcode_header_t *mc_header = mc;186186- struct extended_sigtable *ext_header = NULL;187187- struct extended_signature *ext_sig;188188- unsigned long total_size, data_size, ext_table_size;189189- int sum, orig_sum, ext_sigcount = 0, i;190190-191191- total_size = get_totalsize(mc_header);192192- data_size = get_datasize(mc_header);193193- if (data_size + MC_HEADER_SIZE > total_size) {194194- printk(KERN_ERR "microcode: error! "195195- "Bad data size in microcode data file\n");196196- return -EINVAL;197197- }198198-199199- if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {200200- printk(KERN_ERR "microcode: error! "201201- "Unknown microcode update format\n");202202- return -EINVAL;203203- }204204- ext_table_size = total_size - (MC_HEADER_SIZE + data_size);205205- if (ext_table_size) {206206- if ((ext_table_size < EXT_HEADER_SIZE)207207- || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {208208- printk(KERN_ERR "microcode: error! "209209- "Small exttable size in microcode data file\n");210210- return -EINVAL;211211- }212212- ext_header = mc + MC_HEADER_SIZE + data_size;213213- if (ext_table_size != exttable_size(ext_header)) {214214- printk(KERN_ERR "microcode: error! "215215- "Bad exttable size in microcode data file\n");216216- return -EFAULT;217217- }218218- ext_sigcount = ext_header->count;219219- }220220-221221- /* check extended table checksum */222222- if (ext_table_size) {223223- int ext_table_sum = 0;224224- int *ext_tablep = (int *)ext_header;225225-226226- i = ext_table_size / DWSIZE;227227- while (i--)228228- ext_table_sum += ext_tablep[i];229229- if (ext_table_sum) {230230- printk(KERN_WARNING "microcode: aborting, "231231- "bad extended signature table checksum\n");232232- return -EINVAL;233233- }234234- }235235-236236- /* calculate the checksum */237237- orig_sum = 0;238238- i = (MC_HEADER_SIZE + data_size) / DWSIZE;239239- while (i--)240240- orig_sum += ((int *)mc)[i];241241- if (orig_sum) {242242- printk(KERN_ERR "microcode: aborting, bad checksum\n");243243- return -EINVAL;244244- }245245- if (!ext_table_size)246246- return 0;247247- /* check extended signature checksum */248248- for (i = 0; i < ext_sigcount; i++) {249249- ext_sig = (void *)ext_header + EXT_HEADER_SIZE +250250- EXT_SIGNATURE_SIZE * i;251251- sum = orig_sum252252- - (mc_header->sig + mc_header->pf + mc_header->cksum)253253- + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);254254- if (sum) {255255- printk(KERN_ERR "microcode: aborting, bad checksum\n");256256- return -EINVAL;257257- }258258- }259259- return 0;260260-}261261-262262-/*263263- * return 0 - no update found264264- * return 1 - found update265265- * return < 0 - error266266- */267267-static int get_maching_microcode(void *mc, int cpu)268268-{269269- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;270270- microcode_header_t *mc_header = mc;271271- struct extended_sigtable *ext_header;272272- unsigned long total_size = get_totalsize(mc_header);273273- int ext_sigcount, i;274274- struct extended_signature *ext_sig;275275- void *new_mc;276276-277277- if (microcode_update_match(cpu, mc_header,278278- mc_header->sig, mc_header->pf))279279- goto find;280280-281281- if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)282282- return 0;283283-284284- ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;285285- ext_sigcount = ext_header->count;286286- ext_sig = (void *)ext_header + EXT_HEADER_SIZE;287287- for (i = 0; i < ext_sigcount; i++) {288288- if (microcode_update_match(cpu, mc_header,289289- ext_sig->sig, ext_sig->pf))290290- goto find;291291- ext_sig++;292292- }293293- return 0;294294-find:295295- pr_debug("microcode: CPU%d found a matching microcode update with"296296- " version 0x%x (current=0x%x)\n", cpu, mc_header->rev,uci->rev);297297- new_mc = vmalloc(total_size);298298- if (!new_mc) {299299- printk(KERN_ERR "microcode: error! Can not allocate memory\n");300300- return -ENOMEM;301301- }302302-303303- /* free previous update file */304304- vfree(uci->mc);305305-306306- memcpy(new_mc, mc, total_size);307307- uci->mc = new_mc;308308- return 1;309309-}310310-311311-static void apply_microcode(int cpu)312312-{313313- unsigned long flags;314314- unsigned int val[2];315315- int cpu_num = raw_smp_processor_id();316316- struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;317317-318318- /* We should bind the task to the CPU */319319- BUG_ON(cpu_num != cpu);320320-321321- if (uci->mc == NULL)322322- return;323323-324324- /* serialize access to the physical write to MSR 0x79 */325325- spin_lock_irqsave(µcode_update_lock, flags);326326-327327- /* write microcode via MSR 0x79 */328328- wrmsr(MSR_IA32_UCODE_WRITE,329329- (unsigned long) uci->mc->bits,330330- (unsigned long) uci->mc->bits >> 16 >> 16);331331- wrmsr(MSR_IA32_UCODE_REV, 0, 0);332332-333333- /* see notes above for revision 1.07. Apparent chip bug */334334- sync_core();335335-336336- /* get the current revision from MSR 0x8B */337337- rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);338338-339339- spin_unlock_irqrestore(µcode_update_lock, flags);340340- if (val[1] != uci->mc->hdr.rev) {341341- printk(KERN_ERR "microcode: CPU%d update from revision "342342- "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]);343343- return;344344- }345345- printk(KERN_INFO "microcode: CPU%d updated from revision "346346- "0x%x to 0x%x, date = %08x \n",347347- cpu_num, uci->rev, val[1], uci->mc->hdr.date);348348- uci->rev = val[1];349349-}350350-351351-#ifdef CONFIG_MICROCODE_OLD_INTERFACE352352-static void __user *user_buffer; /* user area microcode data buffer */353353-static unsigned int user_buffer_size; /* it's size */354354-355355-static long get_next_ucode(void **mc, long offset)356356-{357357- microcode_header_t mc_header;358358- unsigned long total_size;359359-360360- /* No more data */361361- if (offset >= user_buffer_size)362362- return 0;363363- if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) {364364- printk(KERN_ERR "microcode: error! Can not read user data\n");365365- return -EFAULT;366366- }367367- total_size = get_totalsize(&mc_header);368368- if (offset + total_size > user_buffer_size) {369369- printk(KERN_ERR "microcode: error! Bad total size in microcode "370370- "data file\n");371371- return -EINVAL;372372- }373373- *mc = vmalloc(total_size);374374- if (!*mc)375375- return -ENOMEM;376376- if (copy_from_user(*mc, user_buffer + offset, total_size)) {377377- printk(KERN_ERR "microcode: error! Can not read user data\n");378378- vfree(*mc);379379- return -EFAULT;380380- }381381- return offset + total_size;382382-}383383-384384-static int do_microcode_update (void)385385-{386386- long cursor = 0;387387- int error = 0;388388- void *new_mc = NULL;389389- int cpu;390390- cpumask_t old;391391-392392- old = current->cpus_allowed;393393-394394- while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) {395395- error = microcode_sanity_check(new_mc);396396- if (error)397397- goto out;398398- /*399399- * It's possible the data file has multiple matching ucode,400400- * lets keep searching till the latest version401401- */402402- for_each_online_cpu(cpu) {403403- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;404404-405405- if (!uci->valid)406406- continue;407407- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));408408- error = get_maching_microcode(new_mc, cpu);409409- if (error < 0)410410- goto out;411411- if (error == 1)412412- apply_microcode(cpu);413413- }414414- vfree(new_mc);415415- }416416-out:417417- if (cursor > 0)418418- vfree(new_mc);419419- if (cursor < 0)420420- error = cursor;421421- set_cpus_allowed_ptr(current, &old);422422- return error;423423-}424424-425425-static int microcode_open (struct inode *unused1, struct file *unused2)426426-{427427- cycle_kernel_lock();428428- return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;429429-}430430-431431-static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)432432-{433433- ssize_t ret;434434-435435- if ((len >> PAGE_SHIFT) > num_physpages) {436436- printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);437437- return -EINVAL;438438- }439439-440440- get_online_cpus();441441- mutex_lock(µcode_mutex);442442-443443- user_buffer = (void __user *) buf;444444- user_buffer_size = (int) len;445445-446446- ret = do_microcode_update();447447- if (!ret)448448- ret = (ssize_t)len;449449-450450- mutex_unlock(µcode_mutex);451451- put_online_cpus();452452-453453- return ret;454454-}455455-456456-static const struct file_operations microcode_fops = {457457- .owner = THIS_MODULE,458458- .write = microcode_write,459459- .open = microcode_open,460460-};461461-462462-static struct miscdevice microcode_dev = {463463- .minor = MICROCODE_MINOR,464464- .name = "microcode",465465- .fops = µcode_fops,466466-};467467-468468-static int __init microcode_dev_init (void)469469-{470470- int error;471471-472472- error = misc_register(µcode_dev);473473- if (error) {474474- printk(KERN_ERR475475- "microcode: can't misc_register on minor=%d\n",476476- MICROCODE_MINOR);477477- return error;478478- }479479-480480- return 0;481481-}482482-483483-static void microcode_dev_exit (void)484484-{485485- misc_deregister(µcode_dev);486486-}487487-488488-MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);489489-#else490490-#define microcode_dev_init() 0491491-#define microcode_dev_exit() do { } while(0)492492-#endif493493-494494-static long get_next_ucode_from_buffer(void **mc, const u8 *buf,495495- unsigned long size, long offset)496496-{497497- microcode_header_t *mc_header;498498- unsigned long total_size;499499-500500- /* No more data */501501- if (offset >= size)502502- return 0;503503- mc_header = (microcode_header_t *)(buf + offset);504504- total_size = get_totalsize(mc_header);505505-506506- if (offset + total_size > size) {507507- printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");508508- return -EINVAL;509509- }510510-511511- *mc = vmalloc(total_size);512512- if (!*mc) {513513- printk(KERN_ERR "microcode: error! Can not allocate memory\n");514514- return -ENOMEM;515515- }516516- memcpy(*mc, buf + offset, total_size);517517- return offset + total_size;518518-}519519-520520-/* fake device for request_firmware */521521-static struct platform_device *microcode_pdev;522522-523523-static int cpu_request_microcode(int cpu)524524-{525525- char name[30];526526- struct cpuinfo_x86 *c = &cpu_data(cpu);527527- const struct firmware *firmware;528528- const u8 *buf;529529- unsigned long size;530530- long offset = 0;531531- int error;532532- void *mc;533533-534534- /* We should bind the task to the CPU */535535- BUG_ON(cpu != raw_smp_processor_id());536536- sprintf(name,"intel-ucode/%02x-%02x-%02x",537537- c->x86, c->x86_model, c->x86_mask);538538- error = request_firmware(&firmware, name, µcode_pdev->dev);539539- if (error) {540540- pr_debug("microcode: data file %s load failed\n", name);541541- return error;542542- }543543- buf = firmware->data;544544- size = firmware->size;545545- while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset))546546- > 0) {547547- error = microcode_sanity_check(mc);548548- if (error)549549- break;550550- error = get_maching_microcode(mc, cpu);551551- if (error < 0)552552- break;553553- /*554554- * It's possible the data file has multiple matching ucode,555555- * lets keep searching till the latest version556556- */557557- if (error == 1) {558558- apply_microcode(cpu);559559- error = 0;560560- }561561- vfree(mc);562562- }563563- if (offset > 0)564564- vfree(mc);565565- if (offset < 0)566566- error = offset;567567- release_firmware(firmware);568568-569569- return error;570570-}571571-572572-static int apply_microcode_check_cpu(int cpu)573573-{574574- struct cpuinfo_x86 *c = &cpu_data(cpu);575575- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;576576- cpumask_t old;577577- unsigned int val[2];578578- int err = 0;579579-580580- /* Check if the microcode is available */581581- if (!uci->mc)582582- return 0;583583-584584- old = current->cpus_allowed;585585- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));586586-587587- /* Check if the microcode we have in memory matches the CPU */588588- if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||589589- cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001))590590- err = -EINVAL;591591-592592- if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) {593593- /* get processor flags from MSR 0x17 */594594- rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);595595- if (uci->pf != (1 << ((val[1] >> 18) & 7)))596596- err = -EINVAL;597597- }598598-599599- if (!err) {600600- wrmsr(MSR_IA32_UCODE_REV, 0, 0);601601- /* see notes above for revision 1.07. Apparent chip bug */602602- sync_core();603603- /* get the current revision from MSR 0x8B */604604- rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);605605- if (uci->rev != val[1])606606- err = -EINVAL;607607- }608608-609609- if (!err)610610- apply_microcode(cpu);611611- else612612- printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:"613613- " sig=0x%x, pf=0x%x, rev=0x%x\n",614614- cpu, uci->sig, uci->pf, uci->rev);615615-616616- set_cpus_allowed_ptr(current, &old);617617- return err;618618-}619619-620620-static void microcode_init_cpu(int cpu, int resume)621621-{622622- cpumask_t old;623623- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;624624-625625- old = current->cpus_allowed;626626-627627- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));628628- mutex_lock(µcode_mutex);629629- collect_cpu_info(cpu);630630- if (uci->valid && system_state == SYSTEM_RUNNING && !resume)631631- cpu_request_microcode(cpu);632632- mutex_unlock(µcode_mutex);633633- set_cpus_allowed_ptr(current, &old);634634-}635635-636636-static void microcode_fini_cpu(int cpu)637637-{638638- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;639639-640640- mutex_lock(µcode_mutex);641641- uci->valid = 0;642642- vfree(uci->mc);643643- uci->mc = NULL;644644- mutex_unlock(µcode_mutex);645645-}646646-647647-static ssize_t reload_store(struct sys_device *dev,648648- struct sysdev_attribute *attr,649649- const char *buf, size_t sz)650650-{651651- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;652652- char *end;653653- unsigned long val = simple_strtoul(buf, &end, 0);654654- int err = 0;655655- int cpu = dev->id;656656-657657- if (end == buf)658658- return -EINVAL;659659- if (val == 1) {660660- cpumask_t old = current->cpus_allowed;661661-662662- get_online_cpus();663663- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));664664-665665- mutex_lock(µcode_mutex);666666- if (uci->valid)667667- err = cpu_request_microcode(cpu);668668- mutex_unlock(µcode_mutex);669669- put_online_cpus();670670- set_cpus_allowed_ptr(current, &old);671671- }672672- if (err)673673- return err;674674- return sz;675675-}676676-677677-static ssize_t version_show(struct sys_device *dev,678678- struct sysdev_attribute *attr, char *buf)679679-{680680- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;681681-682682- return sprintf(buf, "0x%x\n", uci->rev);683683-}684684-685685-static ssize_t pf_show(struct sys_device *dev,686686- struct sysdev_attribute *attr, char *buf)687687-{688688- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;689689-690690- return sprintf(buf, "0x%x\n", uci->pf);691691-}692692-693693-static SYSDEV_ATTR(reload, 0200, NULL, reload_store);694694-static SYSDEV_ATTR(version, 0400, version_show, NULL);695695-static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);696696-697697-static struct attribute *mc_default_attrs[] = {698698- &attr_reload.attr,699699- &attr_version.attr,700700- &attr_processor_flags.attr,701701- NULL702702-};703703-704704-static struct attribute_group mc_attr_group = {705705- .attrs = mc_default_attrs,706706- .name = "microcode",707707-};708708-709709-static int __mc_sysdev_add(struct sys_device *sys_dev, int resume)710710-{711711- int err, cpu = sys_dev->id;712712- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;713713-714714- if (!cpu_online(cpu))715715- return 0;716716-717717- pr_debug("microcode: CPU%d added\n", cpu);718718- memset(uci, 0, sizeof(*uci));719719-720720- err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);721721- if (err)722722- return err;723723-724724- microcode_init_cpu(cpu, resume);725725-726726- return 0;727727-}728728-729729-static int mc_sysdev_add(struct sys_device *sys_dev)730730-{731731- return __mc_sysdev_add(sys_dev, 0);732732-}733733-734734-static int mc_sysdev_remove(struct sys_device *sys_dev)735735-{736736- int cpu = sys_dev->id;737737-738738- if (!cpu_online(cpu))739739- return 0;740740-741741- pr_debug("microcode: CPU%d removed\n", cpu);742742- microcode_fini_cpu(cpu);743743- sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);744744- return 0;745745-}746746-747747-static int mc_sysdev_resume(struct sys_device *dev)748748-{749749- int cpu = dev->id;750750-751751- if (!cpu_online(cpu))752752- return 0;753753- pr_debug("microcode: CPU%d resumed\n", cpu);754754- /* only CPU 0 will apply ucode here */755755- apply_microcode(0);756756- return 0;757757-}758758-759759-static struct sysdev_driver mc_sysdev_driver = {760760- .add = mc_sysdev_add,761761- .remove = mc_sysdev_remove,762762- .resume = mc_sysdev_resume,763763-};764764-765765-static __cpuinit int766766-mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)767767-{768768- unsigned int cpu = (unsigned long)hcpu;769769- struct sys_device *sys_dev;770770-771771- sys_dev = get_cpu_sysdev(cpu);772772- switch (action) {773773- case CPU_UP_CANCELED_FROZEN:774774- /* The CPU refused to come up during a system resume */775775- microcode_fini_cpu(cpu);776776- break;777777- case CPU_ONLINE:778778- case CPU_DOWN_FAILED:779779- mc_sysdev_add(sys_dev);780780- break;781781- case CPU_ONLINE_FROZEN:782782- /* System-wide resume is in progress, try to apply microcode */783783- if (apply_microcode_check_cpu(cpu)) {784784- /* The application of microcode failed */785785- microcode_fini_cpu(cpu);786786- __mc_sysdev_add(sys_dev, 1);787787- break;788788- }789789- case CPU_DOWN_FAILED_FROZEN:790790- if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))791791- printk(KERN_ERR "microcode: Failed to create the sysfs "792792- "group for CPU%d\n", cpu);793793- break;794794- case CPU_DOWN_PREPARE:795795- mc_sysdev_remove(sys_dev);796796- break;797797- case CPU_DOWN_PREPARE_FROZEN:798798- /* Suspend is in progress, only remove the interface */799799- sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);800800- break;801801- }802802- return NOTIFY_OK;803803-}804804-805805-static struct notifier_block __refdata mc_cpu_notifier = {806806- .notifier_call = mc_cpu_callback,807807-};808808-809809-static int __init microcode_init (void)810810-{811811- int error;812812-813813- printk(KERN_INFO814814- "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");815815-816816- error = microcode_dev_init();817817- if (error)818818- return error;819819- microcode_pdev = platform_device_register_simple("microcode", -1,820820- NULL, 0);821821- if (IS_ERR(microcode_pdev)) {822822- microcode_dev_exit();823823- return PTR_ERR(microcode_pdev);824824- }825825-826826- get_online_cpus();827827- error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);828828- put_online_cpus();829829- if (error) {830830- microcode_dev_exit();831831- platform_device_unregister(microcode_pdev);832832- return error;833833- }834834-835835- register_hotcpu_notifier(&mc_cpu_notifier);836836- return 0;837837-}838838-839839-static void __exit microcode_exit (void)840840-{841841- microcode_dev_exit();842842-843843- unregister_hotcpu_notifier(&mc_cpu_notifier);844844-845845- get_online_cpus();846846- sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);847847- put_online_cpus();848848-849849- platform_device_unregister(microcode_pdev);850850-}851851-852852-module_init(microcode_init)853853-module_exit(microcode_exit)
+435
arch/x86/kernel/microcode_amd.c
···11+/*22+ * AMD CPU Microcode Update Driver for Linux33+ * Copyright (C) 2008 Advanced Micro Devices Inc.44+ *55+ * Author: Peter Oruba <peter.oruba@amd.com>66+ *77+ * Based on work by:88+ * Tigran Aivazian <tigran@aivazian.fsnet.co.uk>99+ *1010+ * This driver allows to upgrade microcode on AMD1111+ * family 0x10 and 0x11 processors.1212+ *1313+ * Licensed unter the terms of the GNU General Public1414+ * License version 2. See file COPYING for details.1515+*/1616+1717+#include <linux/capability.h>1818+#include <linux/kernel.h>1919+#include <linux/init.h>2020+#include <linux/sched.h>2121+#include <linux/cpumask.h>2222+#include <linux/module.h>2323+#include <linux/slab.h>2424+#include <linux/vmalloc.h>2525+#include <linux/miscdevice.h>2626+#include <linux/spinlock.h>2727+#include <linux/mm.h>2828+#include <linux/fs.h>2929+#include <linux/mutex.h>3030+#include <linux/cpu.h>3131+#include <linux/firmware.h>3232+#include <linux/platform_device.h>3333+#include <linux/pci.h>3434+#include <linux/pci_ids.h>3535+3636+#include <asm/msr.h>3737+#include <asm/uaccess.h>3838+#include <asm/processor.h>3939+#include <asm/microcode.h>4040+4141+MODULE_DESCRIPTION("AMD Microcode Update Driver");4242+MODULE_AUTHOR("Peter Oruba <peter.oruba@amd.com>");4343+MODULE_LICENSE("GPL v2");4444+4545+#define UCODE_MAGIC 0x00414d444646+#define UCODE_EQUIV_CPU_TABLE_TYPE 0x000000004747+#define UCODE_UCODE_TYPE 0x000000014848+4949+struct equiv_cpu_entry {5050+ unsigned int installed_cpu;5151+ unsigned int fixed_errata_mask;5252+ unsigned int fixed_errata_compare;5353+ unsigned int equiv_cpu;5454+};5555+5656+struct microcode_header_amd {5757+ unsigned int data_code;5858+ unsigned int patch_id;5959+ unsigned char mc_patch_data_id[2];6060+ unsigned char mc_patch_data_len;6161+ unsigned char init_flag;6262+ unsigned int mc_patch_data_checksum;6363+ unsigned int nb_dev_id;6464+ unsigned int sb_dev_id;6565+ unsigned char processor_rev_id[2];6666+ unsigned char nb_rev_id;6767+ unsigned char sb_rev_id;6868+ unsigned char bios_api_rev;6969+ unsigned char reserved1[3];7070+ unsigned int match_reg[8];7171+};7272+7373+struct microcode_amd {7474+ struct microcode_header_amd hdr;7575+ unsigned int mpb[0];7676+};7777+7878+#define UCODE_MAX_SIZE (2048)7979+#define DEFAULT_UCODE_DATASIZE (896)8080+#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd))8181+#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)8282+#define DWSIZE (sizeof(u32))8383+/* For now we support a fixed ucode total size only */8484+#define get_totalsize(mc) \8585+ ((((struct microcode_amd *)mc)->hdr.mc_patch_data_len * 28) \8686+ + MC_HEADER_SIZE)8787+8888+/* serialize access to the physical write */8989+static DEFINE_SPINLOCK(microcode_update_lock);9090+9191+static struct equiv_cpu_entry *equiv_cpu_table;9292+9393+static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)9494+{9595+ struct cpuinfo_x86 *c = &cpu_data(cpu);9696+9797+ memset(csig, 0, sizeof(*csig));9898+9999+ if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {100100+ printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n",101101+ cpu);102102+ return -1;103103+ }104104+105105+ asm volatile("movl %1, %%ecx; rdmsr"106106+ : "=a" (csig->rev)107107+ : "i" (0x0000008B) : "ecx");108108+109109+ printk(KERN_INFO "microcode: collect_cpu_info_amd : patch_id=0x%x\n",110110+ csig->rev);111111+112112+ return 0;113113+}114114+115115+static int get_matching_microcode(int cpu, void *mc, int rev)116116+{117117+ struct microcode_header_amd *mc_header = mc;118118+ struct pci_dev *nb_pci_dev, *sb_pci_dev;119119+ unsigned int current_cpu_id;120120+ unsigned int equiv_cpu_id = 0x00;121121+ unsigned int i = 0;122122+123123+ BUG_ON(equiv_cpu_table == NULL);124124+ current_cpu_id = cpuid_eax(0x00000001);125125+126126+ while (equiv_cpu_table[i].installed_cpu != 0) {127127+ if (current_cpu_id == equiv_cpu_table[i].installed_cpu) {128128+ equiv_cpu_id = equiv_cpu_table[i].equiv_cpu;129129+ break;130130+ }131131+ i++;132132+ }133133+134134+ if (!equiv_cpu_id) {135135+ printk(KERN_ERR "microcode: CPU%d cpu_id "136136+ "not found in equivalent cpu table \n", cpu);137137+ return 0;138138+ }139139+140140+ if ((mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff)) {141141+ printk(KERN_ERR142142+ "microcode: CPU%d patch does not match "143143+ "(patch is %x, cpu extended is %x) \n",144144+ cpu, mc_header->processor_rev_id[0],145145+ (equiv_cpu_id & 0xff));146146+ return 0;147147+ }148148+149149+ if ((mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff)) {150150+ printk(KERN_ERR "microcode: CPU%d patch does not match "151151+ "(patch is %x, cpu base id is %x) \n",152152+ cpu, mc_header->processor_rev_id[1],153153+ ((equiv_cpu_id >> 16) & 0xff));154154+155155+ return 0;156156+ }157157+158158+ /* ucode may be northbridge specific */159159+ if (mc_header->nb_dev_id) {160160+ nb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD,161161+ (mc_header->nb_dev_id & 0xff),162162+ NULL);163163+ if ((!nb_pci_dev) ||164164+ (mc_header->nb_rev_id != nb_pci_dev->revision)) {165165+ printk(KERN_ERR "microcode: CPU%d NB mismatch \n", cpu);166166+ pci_dev_put(nb_pci_dev);167167+ return 0;168168+ }169169+ pci_dev_put(nb_pci_dev);170170+ }171171+172172+ /* ucode may be southbridge specific */173173+ if (mc_header->sb_dev_id) {174174+ sb_pci_dev = pci_get_device(PCI_VENDOR_ID_AMD,175175+ (mc_header->sb_dev_id & 0xff),176176+ NULL);177177+ if ((!sb_pci_dev) ||178178+ (mc_header->sb_rev_id != sb_pci_dev->revision)) {179179+ printk(KERN_ERR "microcode: CPU%d SB mismatch \n", cpu);180180+ pci_dev_put(sb_pci_dev);181181+ return 0;182182+ }183183+ pci_dev_put(sb_pci_dev);184184+ }185185+186186+ if (mc_header->patch_id <= rev)187187+ return 0;188188+189189+ return 1;190190+}191191+192192+static void apply_microcode_amd(int cpu)193193+{194194+ unsigned long flags;195195+ unsigned int eax, edx;196196+ unsigned int rev;197197+ int cpu_num = raw_smp_processor_id();198198+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;199199+ struct microcode_amd *mc_amd = uci->mc;200200+ unsigned long addr;201201+202202+ /* We should bind the task to the CPU */203203+ BUG_ON(cpu_num != cpu);204204+205205+ if (mc_amd == NULL)206206+ return;207207+208208+ spin_lock_irqsave(µcode_update_lock, flags);209209+210210+ addr = (unsigned long)&mc_amd->hdr.data_code;211211+ edx = (unsigned int)(((unsigned long)upper_32_bits(addr)));212212+ eax = (unsigned int)(((unsigned long)lower_32_bits(addr)));213213+214214+ asm volatile("movl %0, %%ecx; wrmsr" :215215+ : "i" (0xc0010020), "a" (eax), "d" (edx) : "ecx");216216+217217+ /* get patch id after patching */218218+ asm volatile("movl %1, %%ecx; rdmsr"219219+ : "=a" (rev)220220+ : "i" (0x0000008B) : "ecx");221221+222222+ spin_unlock_irqrestore(µcode_update_lock, flags);223223+224224+ /* check current patch id and patch's id for match */225225+ if (rev != mc_amd->hdr.patch_id) {226226+ printk(KERN_ERR "microcode: CPU%d update from revision "227227+ "0x%x to 0x%x failed\n", cpu_num,228228+ mc_amd->hdr.patch_id, rev);229229+ return;230230+ }231231+232232+ printk(KERN_INFO "microcode: CPU%d updated from revision "233233+ "0x%x to 0x%x \n",234234+ cpu_num, uci->cpu_sig.rev, mc_amd->hdr.patch_id);235235+236236+ uci->cpu_sig.rev = rev;237237+}238238+239239+static void * get_next_ucode(u8 *buf, unsigned int size,240240+ int (*get_ucode_data)(void *, const void *, size_t),241241+ unsigned int *mc_size)242242+{243243+ unsigned int total_size;244244+#define UCODE_CONTAINER_SECTION_HDR 8245245+ u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];246246+ void *mc;247247+248248+ if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))249249+ return NULL;250250+251251+ if (section_hdr[0] != UCODE_UCODE_TYPE) {252252+ printk(KERN_ERR "microcode: error! "253253+ "Wrong microcode payload type field\n");254254+ return NULL;255255+ }256256+257257+ total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));258258+259259+ printk(KERN_INFO "microcode: size %u, total_size %u\n",260260+ size, total_size);261261+262262+ if (total_size > size || total_size > UCODE_MAX_SIZE) {263263+ printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");264264+ return NULL;265265+ }266266+267267+ mc = vmalloc(UCODE_MAX_SIZE);268268+ if (mc) {269269+ memset(mc, 0, UCODE_MAX_SIZE);270270+ if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, total_size)) {271271+ vfree(mc);272272+ mc = NULL;273273+ } else274274+ *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;275275+ }276276+#undef UCODE_CONTAINER_SECTION_HDR277277+ return mc;278278+}279279+280280+281281+static int install_equiv_cpu_table(u8 *buf,282282+ int (*get_ucode_data)(void *, const void *, size_t))283283+{284284+#define UCODE_CONTAINER_HEADER_SIZE 12285285+ u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];286286+ unsigned int *buf_pos = (unsigned int *)container_hdr;287287+ unsigned long size;288288+289289+ if (get_ucode_data(&container_hdr, buf, UCODE_CONTAINER_HEADER_SIZE))290290+ return 0;291291+292292+ size = buf_pos[2];293293+294294+ if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {295295+ printk(KERN_ERR "microcode: error! "296296+ "Wrong microcode equivalnet cpu table\n");297297+ return 0;298298+ }299299+300300+ equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);301301+ if (!equiv_cpu_table) {302302+ printk(KERN_ERR "microcode: error, can't allocate memory for equiv CPU table\n");303303+ return 0;304304+ }305305+306306+ buf += UCODE_CONTAINER_HEADER_SIZE;307307+ if (get_ucode_data(equiv_cpu_table, buf, size)) {308308+ vfree(equiv_cpu_table);309309+ return 0;310310+ }311311+312312+ return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */313313+#undef UCODE_CONTAINER_HEADER_SIZE314314+}315315+316316+static void free_equiv_cpu_table(void)317317+{318318+ if (equiv_cpu_table) {319319+ vfree(equiv_cpu_table);320320+ equiv_cpu_table = NULL;321321+ }322322+}323323+324324+static int generic_load_microcode(int cpu, void *data, size_t size,325325+ int (*get_ucode_data)(void *, const void *, size_t))326326+{327327+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;328328+ u8 *ucode_ptr = data, *new_mc = NULL, *mc;329329+ int new_rev = uci->cpu_sig.rev;330330+ unsigned int leftover;331331+ unsigned long offset;332332+333333+ offset = install_equiv_cpu_table(ucode_ptr, get_ucode_data);334334+ if (!offset) {335335+ printk(KERN_ERR "microcode: installing equivalent cpu table failed\n");336336+ return -EINVAL;337337+ }338338+339339+ ucode_ptr += offset;340340+ leftover = size - offset;341341+342342+ while (leftover) {343343+ unsigned int uninitialized_var(mc_size);344344+ struct microcode_header_amd *mc_header;345345+346346+ mc = get_next_ucode(ucode_ptr, leftover, get_ucode_data, &mc_size);347347+ if (!mc)348348+ break;349349+350350+ mc_header = (struct microcode_header_amd *)mc;351351+ if (get_matching_microcode(cpu, mc, new_rev)) {352352+ if (new_mc)353353+ vfree(new_mc);354354+ new_rev = mc_header->patch_id;355355+ new_mc = mc;356356+ } else 357357+ vfree(mc);358358+359359+ ucode_ptr += mc_size;360360+ leftover -= mc_size;361361+ }362362+363363+ if (new_mc) {364364+ if (!leftover) {365365+ if (uci->mc)366366+ vfree(uci->mc);367367+ uci->mc = new_mc;368368+ pr_debug("microcode: CPU%d found a matching microcode update with"369369+ " version 0x%x (current=0x%x)\n",370370+ cpu, new_rev, uci->cpu_sig.rev);371371+ } else372372+ vfree(new_mc);373373+ }374374+375375+ free_equiv_cpu_table();376376+377377+ return (int)leftover;378378+}379379+380380+static int get_ucode_fw(void *to, const void *from, size_t n)381381+{382382+ memcpy(to, from, n);383383+ return 0;384384+}385385+386386+static int request_microcode_fw(int cpu, struct device *device)387387+{388388+ const char *fw_name = "amd-ucode/microcode_amd.bin";389389+ const struct firmware *firmware;390390+ int ret;391391+392392+ /* We should bind the task to the CPU */393393+ BUG_ON(cpu != raw_smp_processor_id());394394+395395+ ret = request_firmware(&firmware, fw_name, device);396396+ if (ret) {397397+ printk(KERN_ERR "microcode: ucode data file %s load failed\n", fw_name);398398+ return ret;399399+ }400400+401401+ ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size,402402+ &get_ucode_fw);403403+404404+ release_firmware(firmware);405405+406406+ return ret;407407+}408408+409409+static int request_microcode_user(int cpu, const void __user *buf, size_t size)410410+{411411+ printk(KERN_WARNING "microcode: AMD microcode update via /dev/cpu/microcode"412412+ "is not supported\n");413413+ return -1;414414+}415415+416416+static void microcode_fini_cpu_amd(int cpu)417417+{418418+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;419419+420420+ vfree(uci->mc);421421+ uci->mc = NULL;422422+}423423+424424+static struct microcode_ops microcode_amd_ops = {425425+ .request_microcode_user = request_microcode_user,426426+ .request_microcode_fw = request_microcode_fw,427427+ .collect_cpu_info = collect_cpu_info_amd,428428+ .apply_microcode = apply_microcode_amd,429429+ .microcode_fini_cpu = microcode_fini_cpu_amd,430430+};431431+432432+struct microcode_ops * __init init_amd_microcode(void)433433+{434434+ return µcode_amd_ops;435435+}
+508
arch/x86/kernel/microcode_core.c
···11+/*22+ * Intel CPU Microcode Update Driver for Linux33+ *44+ * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>55+ * 2006 Shaohua Li <shaohua.li@intel.com>66+ *77+ * This driver allows to upgrade microcode on Intel processors88+ * belonging to IA-32 family - PentiumPro, Pentium II,99+ * Pentium III, Xeon, Pentium 4, etc.1010+ *1111+ * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture1212+ * Software Developer's Manual1313+ * Order Number 253668 or free download from:1414+ *1515+ * http://developer.intel.com/design/pentium4/manuals/253668.htm1616+ *1717+ * For more information, go to http://www.urbanmyth.org/microcode1818+ *1919+ * This program is free software; you can redistribute it and/or2020+ * modify it under the terms of the GNU General Public License2121+ * as published by the Free Software Foundation; either version2222+ * 2 of the License, or (at your option) any later version.2323+ *2424+ * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>2525+ * Initial release.2626+ * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>2727+ * Added read() support + cleanups.2828+ * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>2929+ * Added 'device trimming' support. open(O_WRONLY) zeroes3030+ * and frees the saved copy of applied microcode.3131+ * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>3232+ * Made to use devfs (/dev/cpu/microcode) + cleanups.3333+ * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>3434+ * Added misc device support (now uses both devfs and misc).3535+ * Added MICROCODE_IOCFREE ioctl to clear memory.3636+ * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>3737+ * Messages for error cases (non Intel & no suitable microcode).3838+ * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>3939+ * Removed ->release(). Removed exclusive open and status bitmap.4040+ * Added microcode_rwsem to serialize read()/write()/ioctl().4141+ * Removed global kernel lock usage.4242+ * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>4343+ * Write 0 to 0x8B msr and then cpuid before reading revision,4444+ * so that it works even if there were no update done by the4545+ * BIOS. Otherwise, reading from 0x8B gives junk (which happened4646+ * to be 0 on my machine which is why it worked even when I4747+ * disabled update by the BIOS)4848+ * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.4949+ * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and5050+ * Tigran Aivazian <tigran@veritas.com>5151+ * Intel Pentium 4 processor support and bugfixes.5252+ * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>5353+ * Bugfix for HT (Hyper-Threading) enabled processors5454+ * whereby processor resources are shared by all logical processors5555+ * in a single CPU package.5656+ * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and5757+ * Tigran Aivazian <tigran@veritas.com>,5858+ * Serialize updates as required on HT processors due to5959+ * speculative nature of implementation.6060+ * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>6161+ * Fix the panic when writing zero-length microcode chunk.6262+ * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,6363+ * Jun Nakajima <jun.nakajima@intel.com>6464+ * Support for the microcode updates in the new format.6565+ * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>6666+ * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl6767+ * because we no longer hold a copy of applied microcode6868+ * in kernel memory.6969+ * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>7070+ * Fix sigmatch() macro to handle old CPUs with pf == 0.7171+ * Thanks to Stuart Swales for pointing out this bug.7272+ */7373+#include <linux/capability.h>7474+#include <linux/kernel.h>7575+#include <linux/init.h>7676+#include <linux/sched.h>7777+#include <linux/smp_lock.h>7878+#include <linux/cpumask.h>7979+#include <linux/module.h>8080+#include <linux/slab.h>8181+#include <linux/vmalloc.h>8282+#include <linux/miscdevice.h>8383+#include <linux/spinlock.h>8484+#include <linux/mm.h>8585+#include <linux/fs.h>8686+#include <linux/mutex.h>8787+#include <linux/cpu.h>8888+#include <linux/firmware.h>8989+#include <linux/platform_device.h>9090+9191+#include <asm/msr.h>9292+#include <asm/uaccess.h>9393+#include <asm/processor.h>9494+#include <asm/microcode.h>9595+9696+MODULE_DESCRIPTION("Microcode Update Driver");9797+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");9898+MODULE_LICENSE("GPL");9999+100100+#define MICROCODE_VERSION "2.00"101101+102102+struct microcode_ops *microcode_ops;103103+104104+/* no concurrent ->write()s are allowed on /dev/cpu/microcode */105105+static DEFINE_MUTEX(microcode_mutex);106106+107107+struct ucode_cpu_info ucode_cpu_info[NR_CPUS];108108+EXPORT_SYMBOL_GPL(ucode_cpu_info);109109+110110+#ifdef CONFIG_MICROCODE_OLD_INTERFACE111111+static int do_microcode_update(const void __user *buf, size_t size)112112+{113113+ cpumask_t old;114114+ int error = 0;115115+ int cpu;116116+117117+ old = current->cpus_allowed;118118+119119+ for_each_online_cpu(cpu) {120120+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;121121+122122+ if (!uci->valid)123123+ continue;124124+125125+ set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));126126+ error = microcode_ops->request_microcode_user(cpu, buf, size);127127+ if (error < 0)128128+ goto out;129129+ if (!error)130130+ microcode_ops->apply_microcode(cpu);131131+ }132132+out:133133+ set_cpus_allowed_ptr(current, &old);134134+ return error;135135+}136136+137137+static int microcode_open(struct inode *unused1, struct file *unused2)138138+{139139+ cycle_kernel_lock();140140+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;141141+}142142+143143+static ssize_t microcode_write(struct file *file, const char __user *buf,144144+ size_t len, loff_t *ppos)145145+{146146+ ssize_t ret;147147+148148+ if ((len >> PAGE_SHIFT) > num_physpages) {149149+ printk(KERN_ERR "microcode: too much data (max %ld pages)\n",150150+ num_physpages);151151+ return -EINVAL;152152+ }153153+154154+ get_online_cpus();155155+ mutex_lock(µcode_mutex);156156+157157+ ret = do_microcode_update(buf, len);158158+ if (!ret)159159+ ret = (ssize_t)len;160160+161161+ mutex_unlock(µcode_mutex);162162+ put_online_cpus();163163+164164+ return ret;165165+}166166+167167+static const struct file_operations microcode_fops = {168168+ .owner = THIS_MODULE,169169+ .write = microcode_write,170170+ .open = microcode_open,171171+};172172+173173+static struct miscdevice microcode_dev = {174174+ .minor = MICROCODE_MINOR,175175+ .name = "microcode",176176+ .fops = µcode_fops,177177+};178178+179179+static int __init microcode_dev_init(void)180180+{181181+ int error;182182+183183+ error = misc_register(µcode_dev);184184+ if (error) {185185+ printk(KERN_ERR186186+ "microcode: can't misc_register on minor=%d\n",187187+ MICROCODE_MINOR);188188+ return error;189189+ }190190+191191+ return 0;192192+}193193+194194+static void microcode_dev_exit(void)195195+{196196+ misc_deregister(µcode_dev);197197+}198198+199199+MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);200200+#else201201+#define microcode_dev_init() 0202202+#define microcode_dev_exit() do { } while (0)203203+#endif204204+205205+/* fake device for request_firmware */206206+struct platform_device *microcode_pdev;207207+208208+static ssize_t reload_store(struct sys_device *dev,209209+ struct sysdev_attribute *attr,210210+ const char *buf, size_t sz)211211+{212212+ struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;213213+ char *end;214214+ unsigned long val = simple_strtoul(buf, &end, 0);215215+ int err = 0;216216+ int cpu = dev->id;217217+218218+ if (end == buf)219219+ return -EINVAL;220220+ if (val == 1) {221221+ cpumask_t old = current->cpus_allowed;222222+223223+ get_online_cpus();224224+ if (cpu_online(cpu)) {225225+ set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));226226+ mutex_lock(µcode_mutex);227227+ if (uci->valid) {228228+ err = microcode_ops->request_microcode_fw(cpu,229229+ µcode_pdev->dev);230230+ if (!err)231231+ microcode_ops->apply_microcode(cpu);232232+ }233233+ mutex_unlock(µcode_mutex);234234+ set_cpus_allowed_ptr(current, &old);235235+ }236236+ put_online_cpus();237237+ }238238+ if (err)239239+ return err;240240+ return sz;241241+}242242+243243+static ssize_t version_show(struct sys_device *dev,244244+ struct sysdev_attribute *attr, char *buf)245245+{246246+ struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;247247+248248+ return sprintf(buf, "0x%x\n", uci->cpu_sig.rev);249249+}250250+251251+static ssize_t pf_show(struct sys_device *dev,252252+ struct sysdev_attribute *attr, char *buf)253253+{254254+ struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;255255+256256+ return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);257257+}258258+259259+static SYSDEV_ATTR(reload, 0200, NULL, reload_store);260260+static SYSDEV_ATTR(version, 0400, version_show, NULL);261261+static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);262262+263263+static struct attribute *mc_default_attrs[] = {264264+ &attr_reload.attr,265265+ &attr_version.attr,266266+ &attr_processor_flags.attr,267267+ NULL268268+};269269+270270+static struct attribute_group mc_attr_group = {271271+ .attrs = mc_default_attrs,272272+ .name = "microcode",273273+};274274+275275+static void microcode_fini_cpu(int cpu)276276+{277277+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;278278+279279+ mutex_lock(µcode_mutex);280280+ microcode_ops->microcode_fini_cpu(cpu);281281+ uci->valid = 0;282282+ mutex_unlock(µcode_mutex);283283+}284284+285285+static void collect_cpu_info(int cpu)286286+{287287+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;288288+289289+ memset(uci, 0, sizeof(*uci));290290+ if (!microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig))291291+ uci->valid = 1;292292+}293293+294294+static int microcode_resume_cpu(int cpu)295295+{296296+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;297297+ struct cpu_signature nsig;298298+299299+ pr_debug("microcode: CPU%d resumed\n", cpu);300300+301301+ if (!uci->mc)302302+ return 1;303303+304304+ /*305305+ * Let's verify that the 'cached' ucode does belong306306+ * to this cpu (a bit of paranoia):307307+ */308308+ if (microcode_ops->collect_cpu_info(cpu, &nsig)) {309309+ microcode_fini_cpu(cpu);310310+ return -1;311311+ }312312+313313+ if (memcmp(&nsig, &uci->cpu_sig, sizeof(nsig))) {314314+ microcode_fini_cpu(cpu);315315+ /* Should we look for a new ucode here? */316316+ return 1;317317+ }318318+319319+ return 0;320320+}321321+322322+void microcode_update_cpu(int cpu)323323+{324324+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;325325+ int err = 0;326326+327327+ /*328328+ * Check if the system resume is in progress (uci->valid != NULL),329329+ * otherwise just request a firmware:330330+ */331331+ if (uci->valid) {332332+ err = microcode_resume_cpu(cpu);333333+ } else { 334334+ collect_cpu_info(cpu);335335+ if (uci->valid && system_state == SYSTEM_RUNNING)336336+ err = microcode_ops->request_microcode_fw(cpu,337337+ µcode_pdev->dev);338338+ }339339+ if (!err)340340+ microcode_ops->apply_microcode(cpu);341341+}342342+343343+static void microcode_init_cpu(int cpu)344344+{345345+ cpumask_t old = current->cpus_allowed;346346+347347+ set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));348348+ /* We should bind the task to the CPU */349349+ BUG_ON(raw_smp_processor_id() != cpu);350350+351351+ mutex_lock(µcode_mutex);352352+ microcode_update_cpu(cpu);353353+ mutex_unlock(µcode_mutex);354354+355355+ set_cpus_allowed_ptr(current, &old);356356+}357357+358358+static int mc_sysdev_add(struct sys_device *sys_dev)359359+{360360+ int err, cpu = sys_dev->id;361361+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;362362+363363+ if (!cpu_online(cpu))364364+ return 0;365365+366366+ pr_debug("microcode: CPU%d added\n", cpu);367367+ memset(uci, 0, sizeof(*uci));368368+369369+ err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);370370+ if (err)371371+ return err;372372+373373+ microcode_init_cpu(cpu);374374+ return 0;375375+}376376+377377+static int mc_sysdev_remove(struct sys_device *sys_dev)378378+{379379+ int cpu = sys_dev->id;380380+381381+ if (!cpu_online(cpu))382382+ return 0;383383+384384+ pr_debug("microcode: CPU%d removed\n", cpu);385385+ microcode_fini_cpu(cpu);386386+ sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);387387+ return 0;388388+}389389+390390+static int mc_sysdev_resume(struct sys_device *dev)391391+{392392+ int cpu = dev->id;393393+394394+ if (!cpu_online(cpu))395395+ return 0;396396+397397+ /* only CPU 0 will apply ucode here */398398+ microcode_update_cpu(0);399399+ return 0;400400+}401401+402402+static struct sysdev_driver mc_sysdev_driver = {403403+ .add = mc_sysdev_add,404404+ .remove = mc_sysdev_remove,405405+ .resume = mc_sysdev_resume,406406+};407407+408408+static __cpuinit int409409+mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)410410+{411411+ unsigned int cpu = (unsigned long)hcpu;412412+ struct sys_device *sys_dev;413413+414414+ sys_dev = get_cpu_sysdev(cpu);415415+ switch (action) {416416+ case CPU_ONLINE:417417+ case CPU_ONLINE_FROZEN:418418+ microcode_init_cpu(cpu);419419+ case CPU_DOWN_FAILED:420420+ case CPU_DOWN_FAILED_FROZEN:421421+ pr_debug("microcode: CPU%d added\n", cpu);422422+ if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))423423+ printk(KERN_ERR "microcode: Failed to create the sysfs "424424+ "group for CPU%d\n", cpu);425425+ break;426426+ case CPU_DOWN_PREPARE:427427+ case CPU_DOWN_PREPARE_FROZEN:428428+ /* Suspend is in progress, only remove the interface */429429+ sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);430430+ pr_debug("microcode: CPU%d removed\n", cpu);431431+ break;432432+ case CPU_DEAD:433433+ case CPU_UP_CANCELED_FROZEN:434434+ /* The CPU refused to come up during a system resume */435435+ microcode_fini_cpu(cpu);436436+ break;437437+ }438438+ return NOTIFY_OK;439439+}440440+441441+static struct notifier_block __refdata mc_cpu_notifier = {442442+ .notifier_call = mc_cpu_callback,443443+};444444+445445+static int __init microcode_init(void)446446+{447447+ struct cpuinfo_x86 *c = &cpu_data(0);448448+ int error;449449+450450+ if (c->x86_vendor == X86_VENDOR_INTEL)451451+ microcode_ops = init_intel_microcode();452452+ else if (c->x86_vendor == X86_VENDOR_AMD)453453+ microcode_ops = init_amd_microcode();454454+455455+ if (!microcode_ops) {456456+ printk(KERN_ERR "microcode: no support for this CPU vendor\n");457457+ return -ENODEV;458458+ }459459+460460+ error = microcode_dev_init();461461+ if (error)462462+ return error;463463+ microcode_pdev = platform_device_register_simple("microcode", -1,464464+ NULL, 0);465465+ if (IS_ERR(microcode_pdev)) {466466+ microcode_dev_exit();467467+ return PTR_ERR(microcode_pdev);468468+ }469469+470470+ get_online_cpus();471471+ error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);472472+ put_online_cpus();473473+ if (error) {474474+ microcode_dev_exit();475475+ platform_device_unregister(microcode_pdev);476476+ return error;477477+ }478478+479479+ register_hotcpu_notifier(&mc_cpu_notifier);480480+481481+ printk(KERN_INFO482482+ "Microcode Update Driver: v" MICROCODE_VERSION483483+ " <tigran@aivazian.fsnet.co.uk>"484484+ " <peter.oruba@amd.com>\n");485485+486486+ return 0;487487+}488488+489489+static void __exit microcode_exit(void)490490+{491491+ microcode_dev_exit();492492+493493+ unregister_hotcpu_notifier(&mc_cpu_notifier);494494+495495+ get_online_cpus();496496+ sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);497497+ put_online_cpus();498498+499499+ platform_device_unregister(microcode_pdev);500500+501501+ microcode_ops = NULL;502502+503503+ printk(KERN_INFO504504+ "Microcode Update Driver: v" MICROCODE_VERSION " removed.\n");505505+}506506+507507+module_init(microcode_init);508508+module_exit(microcode_exit);
+480
arch/x86/kernel/microcode_intel.c
···11+/*22+ * Intel CPU Microcode Update Driver for Linux33+ *44+ * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>55+ * 2006 Shaohua Li <shaohua.li@intel.com>66+ *77+ * This driver allows to upgrade microcode on Intel processors88+ * belonging to IA-32 family - PentiumPro, Pentium II,99+ * Pentium III, Xeon, Pentium 4, etc.1010+ *1111+ * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture1212+ * Software Developer's Manual1313+ * Order Number 253668 or free download from:1414+ *1515+ * http://developer.intel.com/design/pentium4/manuals/253668.htm1616+ *1717+ * For more information, go to http://www.urbanmyth.org/microcode1818+ *1919+ * This program is free software; you can redistribute it and/or2020+ * modify it under the terms of the GNU General Public License2121+ * as published by the Free Software Foundation; either version2222+ * 2 of the License, or (at your option) any later version.2323+ *2424+ * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>2525+ * Initial release.2626+ * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>2727+ * Added read() support + cleanups.2828+ * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>2929+ * Added 'device trimming' support. open(O_WRONLY) zeroes3030+ * and frees the saved copy of applied microcode.3131+ * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>3232+ * Made to use devfs (/dev/cpu/microcode) + cleanups.3333+ * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>3434+ * Added misc device support (now uses both devfs and misc).3535+ * Added MICROCODE_IOCFREE ioctl to clear memory.3636+ * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>3737+ * Messages for error cases (non Intel & no suitable microcode).3838+ * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>3939+ * Removed ->release(). Removed exclusive open and status bitmap.4040+ * Added microcode_rwsem to serialize read()/write()/ioctl().4141+ * Removed global kernel lock usage.4242+ * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>4343+ * Write 0 to 0x8B msr and then cpuid before reading revision,4444+ * so that it works even if there were no update done by the4545+ * BIOS. Otherwise, reading from 0x8B gives junk (which happened4646+ * to be 0 on my machine which is why it worked even when I4747+ * disabled update by the BIOS)4848+ * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.4949+ * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and5050+ * Tigran Aivazian <tigran@veritas.com>5151+ * Intel Pentium 4 processor support and bugfixes.5252+ * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>5353+ * Bugfix for HT (Hyper-Threading) enabled processors5454+ * whereby processor resources are shared by all logical processors5555+ * in a single CPU package.5656+ * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and5757+ * Tigran Aivazian <tigran@veritas.com>,5858+ * Serialize updates as required on HT processors due to5959+ * speculative nature of implementation.6060+ * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>6161+ * Fix the panic when writing zero-length microcode chunk.6262+ * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,6363+ * Jun Nakajima <jun.nakajima@intel.com>6464+ * Support for the microcode updates in the new format.6565+ * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>6666+ * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl6767+ * because we no longer hold a copy of applied microcode6868+ * in kernel memory.6969+ * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>7070+ * Fix sigmatch() macro to handle old CPUs with pf == 0.7171+ * Thanks to Stuart Swales for pointing out this bug.7272+ */7373+#include <linux/capability.h>7474+#include <linux/kernel.h>7575+#include <linux/init.h>7676+#include <linux/sched.h>7777+#include <linux/smp_lock.h>7878+#include <linux/cpumask.h>7979+#include <linux/module.h>8080+#include <linux/slab.h>8181+#include <linux/vmalloc.h>8282+#include <linux/miscdevice.h>8383+#include <linux/spinlock.h>8484+#include <linux/mm.h>8585+#include <linux/fs.h>8686+#include <linux/mutex.h>8787+#include <linux/cpu.h>8888+#include <linux/firmware.h>8989+#include <linux/platform_device.h>9090+9191+#include <asm/msr.h>9292+#include <asm/uaccess.h>9393+#include <asm/processor.h>9494+#include <asm/microcode.h>9595+9696+MODULE_DESCRIPTION("Microcode Update Driver");9797+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");9898+MODULE_LICENSE("GPL");9999+100100+struct microcode_header_intel {101101+ unsigned int hdrver;102102+ unsigned int rev;103103+ unsigned int date;104104+ unsigned int sig;105105+ unsigned int cksum;106106+ unsigned int ldrver;107107+ unsigned int pf;108108+ unsigned int datasize;109109+ unsigned int totalsize;110110+ unsigned int reserved[3];111111+};112112+113113+struct microcode_intel {114114+ struct microcode_header_intel hdr;115115+ unsigned int bits[0];116116+};117117+118118+/* microcode format is extended from prescott processors */119119+struct extended_signature {120120+ unsigned int sig;121121+ unsigned int pf;122122+ unsigned int cksum;123123+};124124+125125+struct extended_sigtable {126126+ unsigned int count;127127+ unsigned int cksum;128128+ unsigned int reserved[3];129129+ struct extended_signature sigs[0];130130+};131131+132132+#define DEFAULT_UCODE_DATASIZE (2000)133133+#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))134134+#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)135135+#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))136136+#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))137137+#define DWSIZE (sizeof(u32))138138+#define get_totalsize(mc) \139139+ (((struct microcode_intel *)mc)->hdr.totalsize ? \140140+ ((struct microcode_intel *)mc)->hdr.totalsize : \141141+ DEFAULT_UCODE_TOTALSIZE)142142+143143+#define get_datasize(mc) \144144+ (((struct microcode_intel *)mc)->hdr.datasize ? \145145+ ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)146146+147147+#define sigmatch(s1, s2, p1, p2) \148148+ (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))149149+150150+#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)151151+152152+/* serialize access to the physical write to MSR 0x79 */153153+static DEFINE_SPINLOCK(microcode_update_lock);154154+155155+static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)156156+{157157+ struct cpuinfo_x86 *c = &cpu_data(cpu_num);158158+ unsigned int val[2];159159+160160+ memset(csig, 0, sizeof(*csig));161161+162162+ if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||163163+ cpu_has(c, X86_FEATURE_IA64)) {164164+ printk(KERN_ERR "microcode: CPU%d not a capable Intel "165165+ "processor\n", cpu_num);166166+ return -1;167167+ }168168+169169+ csig->sig = cpuid_eax(0x00000001);170170+171171+ if ((c->x86_model >= 5) || (c->x86 > 6)) {172172+ /* get processor flags from MSR 0x17 */173173+ rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);174174+ csig->pf = 1 << ((val[1] >> 18) & 7);175175+ }176176+177177+ wrmsr(MSR_IA32_UCODE_REV, 0, 0);178178+ /* see notes above for revision 1.07. Apparent chip bug */179179+ sync_core();180180+ /* get the current revision from MSR 0x8B */181181+ rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);182182+ pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",183183+ csig->sig, csig->pf, csig->rev);184184+185185+ return 0;186186+}187187+188188+static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)189189+{190190+ return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1;191191+}192192+193193+static inline int 194194+update_match_revision(struct microcode_header_intel *mc_header, int rev)195195+{196196+ return (mc_header->rev <= rev) ? 0 : 1;197197+}198198+199199+static int microcode_sanity_check(void *mc)200200+{201201+ struct microcode_header_intel *mc_header = mc;202202+ struct extended_sigtable *ext_header = NULL;203203+ struct extended_signature *ext_sig;204204+ unsigned long total_size, data_size, ext_table_size;205205+ int sum, orig_sum, ext_sigcount = 0, i;206206+207207+ total_size = get_totalsize(mc_header);208208+ data_size = get_datasize(mc_header);209209+ if (data_size + MC_HEADER_SIZE > total_size) {210210+ printk(KERN_ERR "microcode: error! "211211+ "Bad data size in microcode data file\n");212212+ return -EINVAL;213213+ }214214+215215+ if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {216216+ printk(KERN_ERR "microcode: error! "217217+ "Unknown microcode update format\n");218218+ return -EINVAL;219219+ }220220+ ext_table_size = total_size - (MC_HEADER_SIZE + data_size);221221+ if (ext_table_size) {222222+ if ((ext_table_size < EXT_HEADER_SIZE)223223+ || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {224224+ printk(KERN_ERR "microcode: error! "225225+ "Small exttable size in microcode data file\n");226226+ return -EINVAL;227227+ }228228+ ext_header = mc + MC_HEADER_SIZE + data_size;229229+ if (ext_table_size != exttable_size(ext_header)) {230230+ printk(KERN_ERR "microcode: error! "231231+ "Bad exttable size in microcode data file\n");232232+ return -EFAULT;233233+ }234234+ ext_sigcount = ext_header->count;235235+ }236236+237237+ /* check extended table checksum */238238+ if (ext_table_size) {239239+ int ext_table_sum = 0;240240+ int *ext_tablep = (int *)ext_header;241241+242242+ i = ext_table_size / DWSIZE;243243+ while (i--)244244+ ext_table_sum += ext_tablep[i];245245+ if (ext_table_sum) {246246+ printk(KERN_WARNING "microcode: aborting, "247247+ "bad extended signature table checksum\n");248248+ return -EINVAL;249249+ }250250+ }251251+252252+ /* calculate the checksum */253253+ orig_sum = 0;254254+ i = (MC_HEADER_SIZE + data_size) / DWSIZE;255255+ while (i--)256256+ orig_sum += ((int *)mc)[i];257257+ if (orig_sum) {258258+ printk(KERN_ERR "microcode: aborting, bad checksum\n");259259+ return -EINVAL;260260+ }261261+ if (!ext_table_size)262262+ return 0;263263+ /* check extended signature checksum */264264+ for (i = 0; i < ext_sigcount; i++) {265265+ ext_sig = (void *)ext_header + EXT_HEADER_SIZE +266266+ EXT_SIGNATURE_SIZE * i;267267+ sum = orig_sum268268+ - (mc_header->sig + mc_header->pf + mc_header->cksum)269269+ + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);270270+ if (sum) {271271+ printk(KERN_ERR "microcode: aborting, bad checksum\n");272272+ return -EINVAL;273273+ }274274+ }275275+ return 0;276276+}277277+278278+/*279279+ * return 0 - no update found280280+ * return 1 - found update281281+ */282282+static int283283+get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev)284284+{285285+ struct microcode_header_intel *mc_header = mc;286286+ struct extended_sigtable *ext_header;287287+ unsigned long total_size = get_totalsize(mc_header);288288+ int ext_sigcount, i;289289+ struct extended_signature *ext_sig;290290+291291+ if (!update_match_revision(mc_header, rev))292292+ return 0;293293+294294+ if (update_match_cpu(cpu_sig, mc_header->sig, mc_header->pf))295295+ return 1;296296+297297+ /* Look for ext. headers: */298298+ if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)299299+ return 0;300300+301301+ ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;302302+ ext_sigcount = ext_header->count;303303+ ext_sig = (void *)ext_header + EXT_HEADER_SIZE;304304+305305+ for (i = 0; i < ext_sigcount; i++) {306306+ if (update_match_cpu(cpu_sig, ext_sig->sig, ext_sig->pf))307307+ return 1;308308+ ext_sig++;309309+ }310310+ return 0;311311+}312312+313313+static void apply_microcode(int cpu)314314+{315315+ unsigned long flags;316316+ unsigned int val[2];317317+ int cpu_num = raw_smp_processor_id();318318+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;319319+ struct microcode_intel *mc_intel = uci->mc;320320+321321+ /* We should bind the task to the CPU */322322+ BUG_ON(cpu_num != cpu);323323+324324+ if (mc_intel == NULL)325325+ return;326326+327327+ /* serialize access to the physical write to MSR 0x79 */328328+ spin_lock_irqsave(µcode_update_lock, flags);329329+330330+ /* write microcode via MSR 0x79 */331331+ wrmsr(MSR_IA32_UCODE_WRITE,332332+ (unsigned long) mc_intel->bits,333333+ (unsigned long) mc_intel->bits >> 16 >> 16);334334+ wrmsr(MSR_IA32_UCODE_REV, 0, 0);335335+336336+ /* see notes above for revision 1.07. Apparent chip bug */337337+ sync_core();338338+339339+ /* get the current revision from MSR 0x8B */340340+ rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);341341+342342+ spin_unlock_irqrestore(µcode_update_lock, flags);343343+ if (val[1] != mc_intel->hdr.rev) {344344+ printk(KERN_ERR "microcode: CPU%d update from revision "345345+ "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]);346346+ return;347347+ }348348+ printk(KERN_INFO "microcode: CPU%d updated from revision "349349+ "0x%x to 0x%x, date = %04x-%02x-%02x \n",350350+ cpu_num, uci->cpu_sig.rev, val[1],351351+ mc_intel->hdr.date & 0xffff,352352+ mc_intel->hdr.date >> 24,353353+ (mc_intel->hdr.date >> 16) & 0xff);354354+ uci->cpu_sig.rev = val[1];355355+}356356+357357+static int generic_load_microcode(int cpu, void *data, size_t size,358358+ int (*get_ucode_data)(void *, const void *, size_t))359359+{360360+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;361361+ u8 *ucode_ptr = data, *new_mc = NULL, *mc;362362+ int new_rev = uci->cpu_sig.rev;363363+ unsigned int leftover = size;364364+365365+ while (leftover) {366366+ struct microcode_header_intel mc_header;367367+ unsigned int mc_size;368368+369369+ if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header)))370370+ break;371371+372372+ mc_size = get_totalsize(&mc_header);373373+ if (!mc_size || mc_size > leftover) {374374+ printk(KERN_ERR "microcode: error!"375375+ "Bad data in microcode data file\n");376376+ break;377377+ }378378+379379+ mc = vmalloc(mc_size);380380+ if (!mc)381381+ break;382382+383383+ if (get_ucode_data(mc, ucode_ptr, mc_size) ||384384+ microcode_sanity_check(mc) < 0) {385385+ vfree(mc);386386+ break;387387+ }388388+389389+ if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {390390+ if (new_mc)391391+ vfree(new_mc);392392+ new_rev = mc_header.rev;393393+ new_mc = mc;394394+ } else395395+ vfree(mc);396396+397397+ ucode_ptr += mc_size;398398+ leftover -= mc_size;399399+ }400400+401401+ if (new_mc) {402402+ if (!leftover) {403403+ if (uci->mc)404404+ vfree(uci->mc);405405+ uci->mc = (struct microcode_intel *)new_mc;406406+ pr_debug("microcode: CPU%d found a matching microcode update with"407407+ " version 0x%x (current=0x%x)\n",408408+ cpu, new_rev, uci->cpu_sig.rev);409409+ } else410410+ vfree(new_mc);411411+ }412412+413413+ return (int)leftover;414414+}415415+416416+static int get_ucode_fw(void *to, const void *from, size_t n)417417+{418418+ memcpy(to, from, n);419419+ return 0;420420+}421421+422422+static int request_microcode_fw(int cpu, struct device *device)423423+{424424+ char name[30];425425+ struct cpuinfo_x86 *c = &cpu_data(cpu);426426+ const struct firmware *firmware;427427+ int ret;428428+429429+ /* We should bind the task to the CPU */430430+ BUG_ON(cpu != raw_smp_processor_id());431431+ sprintf(name, "intel-ucode/%02x-%02x-%02x",432432+ c->x86, c->x86_model, c->x86_mask);433433+ ret = request_firmware(&firmware, name, device);434434+ if (ret) {435435+ pr_debug("microcode: data file %s load failed\n", name);436436+ return ret;437437+ }438438+439439+ ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size,440440+ &get_ucode_fw);441441+442442+ release_firmware(firmware);443443+444444+ return ret;445445+}446446+447447+static int get_ucode_user(void *to, const void *from, size_t n)448448+{449449+ return copy_from_user(to, from, n);450450+}451451+452452+static int request_microcode_user(int cpu, const void __user *buf, size_t size)453453+{454454+ /* We should bind the task to the CPU */455455+ BUG_ON(cpu != raw_smp_processor_id());456456+457457+ return generic_load_microcode(cpu, (void*)buf, size, &get_ucode_user);458458+}459459+460460+static void microcode_fini_cpu(int cpu)461461+{462462+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;463463+464464+ vfree(uci->mc);465465+ uci->mc = NULL;466466+}467467+468468+struct microcode_ops microcode_intel_ops = {469469+ .request_microcode_user = request_microcode_user,470470+ .request_microcode_fw = request_microcode_fw,471471+ .collect_cpu_info = collect_cpu_info,472472+ .apply_microcode = apply_microcode,473473+ .microcode_fini_cpu = microcode_fini_cpu,474474+};475475+476476+struct microcode_ops * __init init_intel_microcode(void)477477+{478478+ return µcode_intel_ops;479479+}480480+
+37
arch/x86/kernel/paravirt-spinlocks.c
···11+/*22+ * Split spinlock implementation out into its own file, so it can be33+ * compiled in a FTRACE-compatible way.44+ */55+#include <linux/spinlock.h>66+#include <linux/module.h>77+88+#include <asm/paravirt.h>99+1010+static void default_spin_lock_flags(struct raw_spinlock *lock, unsigned long flags)1111+{1212+ __raw_spin_lock(lock);1313+}1414+1515+struct pv_lock_ops pv_lock_ops = {1616+#ifdef CONFIG_SMP1717+ .spin_is_locked = __ticket_spin_is_locked,1818+ .spin_is_contended = __ticket_spin_is_contended,1919+2020+ .spin_lock = __ticket_spin_lock,2121+ .spin_lock_flags = default_spin_lock_flags,2222+ .spin_trylock = __ticket_spin_trylock,2323+ .spin_unlock = __ticket_spin_unlock,2424+#endif2525+};2626+EXPORT_SYMBOL(pv_lock_ops);2727+2828+void __init paravirt_use_bytelocks(void)2929+{3030+#ifdef CONFIG_SMP3131+ pv_lock_ops.spin_is_locked = __byte_spin_is_locked;3232+ pv_lock_ops.spin_is_contended = __byte_spin_is_contended;3333+ pv_lock_ops.spin_lock = __byte_spin_lock;3434+ pv_lock_ops.spin_trylock = __byte_spin_trylock;3535+ pv_lock_ops.spin_unlock = __byte_spin_unlock;3636+#endif3737+}
···7676 return ((unsigned long *)tsk->thread.sp)[3];7777}78787979-#ifdef CONFIG_HOTPLUG_CPU8080-#include <asm/nmi.h>8181-8282-static void cpu_exit_clear(void)8383-{8484- int cpu = raw_smp_processor_id();8585-8686- idle_task_exit();8787-8888- cpu_uninit();8989- irq_ctx_exit(cpu);9090-9191- cpu_clear(cpu, cpu_callout_map);9292- cpu_clear(cpu, cpu_callin_map);9393-9494- numa_remove_cpu(cpu);9595- c1e_remove_cpu(cpu);9696-}9797-9898-/* We don't actually take CPU down, just spin without interrupts. */9999-static inline void play_dead(void)100100-{101101- /* This must be done before dead CPU ack */102102- cpu_exit_clear();103103- mb();104104- /* Ack it */105105- __get_cpu_var(cpu_state) = CPU_DEAD;106106-107107- /*108108- * With physical CPU hotplug, we should halt the cpu109109- */110110- local_irq_disable();111111- /* mask all interrupts, flush any and all caches, and halt */112112- wbinvd_halt();113113-}114114-#else7979+#ifndef CONFIG_SMP11580static inline void play_dead(void)11681{11782 BUG();11883}119119-#endif /* CONFIG_HOTPLUG_CPU */8484+#endif1208512186/*12287 * The idle thread. There's no useful work to be
+2-20
arch/x86/kernel/process_64.c
···8686 __exit_idle();8787}88888989-#ifdef CONFIG_HOTPLUG_CPU9090-DECLARE_PER_CPU(int, cpu_state);9191-9292-#include <linux/nmi.h>9393-/* We halt the CPU with physical CPU hotplug */9494-static inline void play_dead(void)9595-{9696- idle_task_exit();9797- c1e_remove_cpu(raw_smp_processor_id());9898-9999- mb();100100- /* Ack it */101101- __get_cpu_var(cpu_state) = CPU_DEAD;102102-103103- local_irq_disable();104104- /* mask all interrupts, flush any and all caches, and halt */105105- wbinvd_halt();106106-}107107-#else8989+#ifndef CONFIG_SMP10890static inline void play_dead(void)10991{11092 BUG();11193}112112-#endif /* CONFIG_HOTPLUG_CPU */9494+#endif1139511496/*11597 * The idle thread. There's no useful work to be
···5252#include <asm/desc.h>5353#include <asm/nmi.h>5454#include <asm/irq.h>5555+#include <asm/idle.h>5556#include <asm/smp.h>5657#include <asm/trampoline.h>5758#include <asm/cpu.h>···13451344 numa_remove_cpu(cpu);13461345}1347134613481348-int __cpu_disable(void)13471347+void cpu_disable_common(void)13481348+{13491349+ int cpu = smp_processor_id();13501350+ /*13511351+ * HACK:13521352+ * Allow any queued timer interrupts to get serviced13531353+ * This is only a temporary solution until we cleanup13541354+ * fixup_irqs as we do for IA64.13551355+ */13561356+ local_irq_enable();13571357+ mdelay(1);13581358+13591359+ local_irq_disable();13601360+ remove_siblinginfo(cpu);13611361+13621362+ /* It's now safe to remove this processor from the online map */13631363+ lock_vector_lock();13641364+ remove_cpu_from_maps(cpu);13651365+ unlock_vector_lock();13661366+ fixup_irqs(cpu_online_map);13671367+}13681368+13691369+int native_cpu_disable(void)13491370{13501371 int cpu = smp_processor_id();13511372···13861363 stop_apic_nmi_watchdog(NULL);13871364 clear_local_APIC();1388136513891389- /*13901390- * HACK:13911391- * Allow any queued timer interrupts to get serviced13921392- * This is only a temporary solution until we cleanup13931393- * fixup_irqs as we do for IA64.13941394- */13951395- local_irq_enable();13961396- mdelay(1);13971397-13981398- local_irq_disable();13991399- remove_siblinginfo(cpu);14001400-14011401- /* It's now safe to remove this processor from the online map */14021402- lock_vector_lock();14031403- remove_cpu_from_maps(cpu);14041404- unlock_vector_lock();14051405- fixup_irqs(cpu_online_map);13661366+ cpu_disable_common();14061367 return 0;14071368}1408136914091409-void __cpu_die(unsigned int cpu)13701370+void native_cpu_die(unsigned int cpu)14101371{14111372 /* We don't do anything here: idle task is faking death itself. */14121373 unsigned int i;···14071400 }14081401 printk(KERN_ERR "CPU %u didn't die...\n", cpu);14091402}14031403+14041404+void play_dead_common(void)14051405+{14061406+ idle_task_exit();14071407+ reset_lazy_tlbstate();14081408+ irq_ctx_exit(raw_smp_processor_id());14091409+ c1e_remove_cpu(raw_smp_processor_id());14101410+14111411+ mb();14121412+ /* Ack it */14131413+ __get_cpu_var(cpu_state) = CPU_DEAD;14141414+14151415+ /*14161416+ * With physical CPU hotplug, we should halt the cpu14171417+ */14181418+ local_irq_disable();14191419+}14201420+14211421+void native_play_dead(void)14221422+{14231423+ play_dead_common();14241424+ wbinvd_halt();14251425+}14261426+14101427#else /* ... !CONFIG_HOTPLUG_CPU */14111411-int __cpu_disable(void)14281428+int native_cpu_disable(void)14121429{14131430 return -ENOSYS;14141431}1415143214161416-void __cpu_die(unsigned int cpu)14331433+void native_cpu_die(unsigned int cpu)14171434{14181435 /* We said "no" in __cpu_disable */14191436 BUG();14201437}14381438+14391439+void native_play_dead(void)14401440+{14411441+ BUG();14421442+}14431443+14211444#endif
+8
arch/x86/kernel/tlb_32.c
···241241 on_each_cpu(do_flush_tlb_all, NULL, 1);242242}243243244244+void reset_lazy_tlbstate(void)245245+{246246+ int cpu = raw_smp_processor_id();247247+248248+ per_cpu(cpu_tlbstate, cpu).state = 0;249249+ per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;250250+}251251+
+3-1
arch/x86/kernel/traps_32.c
···891891{892892 struct task_struct *tsk = current;893893 unsigned int condition;894894+ int si_code;894895895896 trace_hardirqs_fixup();896897···936935 goto clear_TF_reenable;937936 }938937938938+ si_code = get_si_code((unsigned long)condition);939939 /* Ok, finally something we can handle */940940- send_sigtrap(tsk, regs, error_code);940940+ send_sigtrap(tsk, regs, error_code, si_code);941941942942 /*943943 * Disable additional traps. They'll be re-enabled when
···9595 * Start with clearing the user buffer. This will present a9696 * clean context for the bytes not touched by the fxsave/xsave.9797 */9898- __clear_user(buf, sig_xstate_size);9898+ err = __clear_user(buf, sig_xstate_size);9999+ if (err)100100+ return err;99101100102 if (task_thread_info(tsk)->status & TS_XSAVE)101103 err = xsave_user(buf);···116114117115 if (task_thread_info(tsk)->status & TS_XSAVE) {118116 struct _fpstate __user *fx = buf;117117+ struct _xstate __user *x = buf;118118+ u64 xstate_bv;119119120120 err = __copy_to_user(&fx->sw_reserved, &fx_sw_reserved,121121 sizeof(struct _fpx_sw_bytes));···125121 err |= __put_user(FP_XSTATE_MAGIC2,126122 (__u32 __user *) (buf + sig_xstate_size127123 - FP_XSTATE_MAGIC2_SIZE));124124+125125+ /*126126+ * Read the xstate_bv which we copied (directly from the cpu or127127+ * from the state in task struct) to the user buffers and128128+ * set the FP/SSE bits.129129+ */130130+ err |= __get_user(xstate_bv, &x->xstate_hdr.xstate_bv);131131+132132+ /*133133+ * For legacy compatible, we always set FP/SSE bits in the bit134134+ * vector while saving the state to the user context. This will135135+ * enable us capturing any changes(during sigreturn) to136136+ * the FP/SSE bits by the legacy applications which don't touch137137+ * xstate_bv in the xsave header.138138+ *139139+ * xsave aware apps can change the xstate_bv in the xsave140140+ * header as well as change any contents in the memory layout.141141+ * xrestore as part of sigreturn will capture all the changes.142142+ */143143+ xstate_bv |= XSTATE_FPSSE;144144+145145+ err |= __put_user(xstate_bv, &x->xstate_hdr.xstate_bv);146146+147147+ if (err)148148+ return err;128149 }129150130151 return 1;···301272/*302273 * setup the xstate image representing the init state303274 */304304-void setup_xstate_init(void)275275+static void __init setup_xstate_init(void)305276{306277 init_xstate_buf = alloc_bootmem(xstate_size);307278 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
+6-8
arch/x86/mm/fault.c
···914914915915void vmalloc_sync_all(void)916916{917917-#ifdef CONFIG_X86_32918918- unsigned long start = VMALLOC_START & PGDIR_MASK;919917 unsigned long address;920918919919+#ifdef CONFIG_X86_32921920 if (SHARED_KERNEL_PMD)922921 return;923922924924- BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);925925- for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) {923923+ for (address = VMALLOC_START & PMD_MASK;924924+ address >= TASK_SIZE && address < FIXADDR_TOP;925925+ address += PMD_SIZE) {926926 unsigned long flags;927927 struct page *page;928928···935935 spin_unlock_irqrestore(&pgd_lock, flags);936936 }937937#else /* CONFIG_X86_64 */938938- unsigned long start = VMALLOC_START & PGDIR_MASK;939939- unsigned long address;940940-941941- for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {938938+ for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;939939+ address += PGDIR_SIZE) {942940 const pgd_t *pgd_ref = pgd_offset_k(address);943941 unsigned long flags;944942 struct page *page;
+3
arch/x86/mm/init_32.c
···3131#include <linux/cpumask.h>32323333#include <asm/asm.h>3434+#include <asm/bios_ebda.h>3435#include <asm/processor.h>3536#include <asm/system.h>3637#include <asm/uaccess.h>···969968{970969 int codesize, reservedpages, datasize, initsize;971970 int tmp;971971+972972+ start_periodic_check_for_corruption();972973973974#ifdef CONFIG_FLATMEM974975 BUG_ON(!mem_map);
···24242525#ifdef CONFIG_X86_6426262727-unsigned long __phys_addr(unsigned long x)2828-{2929- if (x >= __START_KERNEL_map)3030- return x - __START_KERNEL_map + phys_base;3131- return x - PAGE_OFFSET;3232-}3333-EXPORT_SYMBOL(__phys_addr);3434-3527static inline int phys_addr_valid(unsigned long addr)3628{3729 return addr < (1UL << boot_cpu_data.x86_phys_bits);3830}3131+3232+unsigned long __phys_addr(unsigned long x)3333+{3434+ if (x >= __START_KERNEL_map) {3535+ x -= __START_KERNEL_map;3636+ VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);3737+ x += phys_base;3838+ } else {3939+ VIRTUAL_BUG_ON(x < PAGE_OFFSET);4040+ x -= PAGE_OFFSET;4141+ VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :4242+ !phys_addr_valid(x));4343+ }4444+ return x;4545+}4646+EXPORT_SYMBOL(__phys_addr);39474048#else4149···5143{5244 return 1;5345}4646+4747+#ifdef CONFIG_DEBUG_VIRTUAL4848+unsigned long __phys_addr(unsigned long x)4949+{5050+ /* VMALLOC_* aren't constants; not available at the boot time */5151+ VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING &&5252+ is_vmalloc_addr((void *)x)));5353+ return x - PAGE_OFFSET;5454+}5555+EXPORT_SYMBOL(__phys_addr);5656+#endif54575558#endif5659
+9-1
arch/x86/xen/Kconfig
···26262727config XEN_SAVE_RESTORE2828 bool2929- depends on PM2929+ depends on XEN && PM3030 default y3131+3232+config XEN_DEBUG_FS3333+ bool "Enable Xen debug and tuning parameters in debugfs"3434+ depends on XEN && DEBUG_FS3535+ default n3636+ help3737+ Enable statistics output and various tuning options in debugfs.3838+ Enabling this option may incur a significant performance overhead.
···3030#include <xen/interface/xen.h>3131#include <xen/interface/physdev.h>3232#include <xen/interface/vcpu.h>3333-#include <xen/interface/sched.h>3433#include <xen/features.h>3534#include <xen/page.h>3635#include <xen/hvc-console.h>···56575758DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);5859DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);6060+6161+enum xen_domain_type xen_domain_type = XEN_NATIVE;6262+EXPORT_SYMBOL_GPL(xen_domain_type);59636064/*6165 * Identity map, in addition to plain kernel map. This needs to be···113111 *114112 * 0: not available, 1: available115113 */116116-static int have_vcpu_info_placement = 1;114114+static int have_vcpu_info_placement =115115+#ifdef CONFIG_X86_32116116+ 1117117+#else118118+ 0119119+#endif120120+ ;121121+117122118123static void xen_vcpu_setup(int cpu)119124{···236227 return HYPERVISOR_get_debugreg(reg);237228}238229239239-static unsigned long xen_save_fl(void)240240-{241241- struct vcpu_info *vcpu;242242- unsigned long flags;243243-244244- vcpu = x86_read_percpu(xen_vcpu);245245-246246- /* flag has opposite sense of mask */247247- flags = !vcpu->evtchn_upcall_mask;248248-249249- /* convert to IF type flag250250- -0 -> 0x00000000251251- -1 -> 0xffffffff252252- */253253- return (-flags) & X86_EFLAGS_IF;254254-}255255-256256-static void xen_restore_fl(unsigned long flags)257257-{258258- struct vcpu_info *vcpu;259259-260260- /* convert from IF type flag */261261- flags = !(flags & X86_EFLAGS_IF);262262-263263- /* There's a one instruction preempt window here. We need to264264- make sure we're don't switch CPUs between getting the vcpu265265- pointer and updating the mask. */266266- preempt_disable();267267- vcpu = x86_read_percpu(xen_vcpu);268268- vcpu->evtchn_upcall_mask = flags;269269- preempt_enable_no_resched();270270-271271- /* Doesn't matter if we get preempted here, because any272272- pending event will get dealt with anyway. */273273-274274- if (flags == 0) {275275- preempt_check_resched();276276- barrier(); /* unmask then check (avoid races) */277277- if (unlikely(vcpu->evtchn_upcall_pending))278278- force_evtchn_callback();279279- }280280-}281281-282282-static void xen_irq_disable(void)283283-{284284- /* There's a one instruction preempt window here. We need to285285- make sure we're don't switch CPUs between getting the vcpu286286- pointer and updating the mask. */287287- preempt_disable();288288- x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;289289- preempt_enable_no_resched();290290-}291291-292292-static void xen_irq_enable(void)293293-{294294- struct vcpu_info *vcpu;295295-296296- /* We don't need to worry about being preempted here, since297297- either a) interrupts are disabled, so no preemption, or b)298298- the caller is confused and is trying to re-enable interrupts299299- on an indeterminate processor. */300300-301301- vcpu = x86_read_percpu(xen_vcpu);302302- vcpu->evtchn_upcall_mask = 0;303303-304304- /* Doesn't matter if we get preempted here, because any305305- pending event will get dealt with anyway. */306306-307307- barrier(); /* unmask then check (avoid races) */308308- if (unlikely(vcpu->evtchn_upcall_pending))309309- force_evtchn_callback();310310-}311311-312312-static void xen_safe_halt(void)313313-{314314- /* Blocking includes an implicit local_irq_enable(). */315315- if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)316316- BUG();317317-}318318-319319-static void xen_halt(void)320320-{321321- if (irqs_disabled())322322- HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);323323- else324324- xen_safe_halt();325325-}326326-327230static void xen_leave_lazy(void)328231{329232 paravirt_leave_lazy(paravirt_get_lazy_mode());···245324static unsigned long xen_store_tr(void)246325{247326 return 0;327327+}328328+329329+/*330330+ * Set the page permissions for a particular virtual address. If the331331+ * address is a vmalloc mapping (or other non-linear mapping), then332332+ * find the linear mapping of the page and also set its protections to333333+ * match.334334+ */335335+static void set_aliased_prot(void *v, pgprot_t prot)336336+{337337+ int level;338338+ pte_t *ptep;339339+ pte_t pte;340340+ unsigned long pfn;341341+ struct page *page;342342+343343+ ptep = lookup_address((unsigned long)v, &level);344344+ BUG_ON(ptep == NULL);345345+346346+ pfn = pte_pfn(*ptep);347347+ page = pfn_to_page(pfn);348348+349349+ pte = pfn_pte(pfn, prot);350350+351351+ if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))352352+ BUG();353353+354354+ if (!PageHighMem(page)) {355355+ void *av = __va(PFN_PHYS(pfn));356356+357357+ if (av != v)358358+ if (HYPERVISOR_update_va_mapping((unsigned long)av, pte, 0))359359+ BUG();360360+ } else361361+ kmap_flush_unused();362362+}363363+364364+static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)365365+{366366+ const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;367367+ int i;368368+369369+ for(i = 0; i < entries; i += entries_per_page)370370+ set_aliased_prot(ldt + i, PAGE_KERNEL_RO);371371+}372372+373373+static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)374374+{375375+ const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;376376+ int i;377377+378378+ for(i = 0; i < entries; i += entries_per_page)379379+ set_aliased_prot(ldt + i, PAGE_KERNEL);248380}249381250382static void xen_set_ldt(const void *addr, unsigned entries)···400426static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,401427 const void *ptr)402428{403403- unsigned long lp = (unsigned long)&dt[entrynum];404404- xmaddr_t mach_lp = virt_to_machine(lp);429429+ xmaddr_t mach_lp = arbitrary_virt_to_machine(&dt[entrynum]);405430 u64 entry = *(u64 *)ptr;406431407432 preempt_disable();···533560}534561535562static void xen_load_sp0(struct tss_struct *tss,536536- struct thread_struct *thread)563563+ struct thread_struct *thread)537564{538565 struct multicall_space mcs = xen_mc_entry(0);539566 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0);···808835 ret = -EFAULT;809836 break;810837#endif838838+839839+ case MSR_STAR:840840+ case MSR_CSTAR:841841+ case MSR_LSTAR:842842+ case MSR_SYSCALL_MASK:843843+ case MSR_IA32_SYSENTER_CS:844844+ case MSR_IA32_SYSENTER_ESP:845845+ case MSR_IA32_SYSENTER_EIP:846846+ /* Fast syscall setup is all done in hypercalls, so847847+ these are all ignored. Stub them out here to stop848848+ Xen console noise. */849849+ break;850850+811851 default:812852 ret = native_write_msr_safe(msr, low, high);813853 }···864878 SetPagePinned(page);865879866880 if (!PageHighMem(page)) {867867- make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));868868- if (level == PT_PTE)881881+ make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn)));882882+ if (level == PT_PTE && USE_SPLIT_PTLOCKS)869883 pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);870884 } else871885 /* make sure there are no stray mappings of···933947934948 if (PagePinned(page)) {935949 if (!PageHighMem(page)) {936936- if (level == PT_PTE)950950+ if (level == PT_PTE && USE_SPLIT_PTLOCKS)937951 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);938952 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));939953 }···980994}981995#endif982996997997+#ifdef CONFIG_X86_32983998static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)984999{9851000 /* If there's an existing pte, then don't allow _PAGE_RW to be set */···999101210001013 xen_set_pte(ptep, pte);10011014}10151015+#endif1002101610031017static __init void xen_pagetable_setup_start(pgd_t *base)10041018{···1066107810671079 /* xen_vcpu_setup managed to place the vcpu_info within the10681080 percpu area for all cpus, so make use of it */10691069-#ifdef CONFIG_X86_3210701081 if (have_vcpu_info_placement) {10711082 printk(KERN_INFO "Xen: using vcpu_info placement\n");10721083···10751088 pv_irq_ops.irq_enable = xen_irq_enable_direct;10761089 pv_mmu_ops.read_cr2 = xen_read_cr2_direct;10771090 }10781078-#endif10791091}1080109210811093static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,···10951109 goto patch_site1096111010971111 switch (type) {10981098-#ifdef CONFIG_X86_3210991112 SITE(pv_irq_ops, irq_enable);11001113 SITE(pv_irq_ops, irq_disable);11011114 SITE(pv_irq_ops, save_fl);11021115 SITE(pv_irq_ops, restore_fl);11031103-#endif /* CONFIG_X86_32 */11041116#undef SITE1105111711061118 patch_site:···12361252 .load_gs_index = xen_load_gs_index,12371253#endif1238125412551255+ .alloc_ldt = xen_alloc_ldt,12561256+ .free_ldt = xen_free_ldt,12571257+12391258 .store_gdt = native_store_gdt,12401259 .store_idt = native_store_idt,12411260 .store_tr = xen_store_tr,···12581271 .enter = paravirt_enter_lazy_cpu,12591272 .leave = xen_leave_lazy,12601273 },12611261-};12621262-12631263-static void __init __xen_init_IRQ(void)12641264-{12651265-#ifdef CONFIG_X86_6412661266- int i;12671267-12681268- /* Create identity vector->irq map */12691269- for(i = 0; i < NR_VECTORS; i++) {12701270- int cpu;12711271-12721272- for_each_possible_cpu(cpu)12731273- per_cpu(vector_irq, cpu)[i] = i;12741274- }12751275-#endif /* CONFIG_X86_64 */12761276-12771277- xen_init_IRQ();12781278-}12791279-12801280-static const struct pv_irq_ops xen_irq_ops __initdata = {12811281- .init_IRQ = __xen_init_IRQ,12821282- .save_fl = xen_save_fl,12831283- .restore_fl = xen_restore_fl,12841284- .irq_disable = xen_irq_disable,12851285- .irq_enable = xen_irq_enable,12861286- .safe_halt = xen_safe_halt,12871287- .halt = xen_halt,12881288-#ifdef CONFIG_X86_6412891289- .adjust_exception_frame = xen_adjust_exception_frame,12901290-#endif12911274};1292127512931276static const struct pv_apic_ops xen_apic_ops __initdata = {···14001443 if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)14011444 top = pp.virt_start;1402144514031403- reserve_top_address(-top + 2 * PAGE_SIZE);14461446+ reserve_top_address(-top);14041447#endif /* CONFIG_X86_32 */14051448}14061449···14341477 return __ka(m2p(maddr));14351478}1436147914371437-#ifdef CONFIG_X86_6414381438-static void walk(pgd_t *pgd, unsigned long addr)14391439-{14401440- unsigned l4idx = pgd_index(addr);14411441- unsigned l3idx = pud_index(addr);14421442- unsigned l2idx = pmd_index(addr);14431443- unsigned l1idx = pte_index(addr);14441444- pgd_t l4;14451445- pud_t l3;14461446- pmd_t l2;14471447- pte_t l1;14481448-14491449- xen_raw_printk("walk %p, %lx -> %d %d %d %d\n",14501450- pgd, addr, l4idx, l3idx, l2idx, l1idx);14511451-14521452- l4 = pgd[l4idx];14531453- xen_raw_printk(" l4: %016lx\n", l4.pgd);14541454- xen_raw_printk(" %016lx\n", pgd_val(l4));14551455-14561456- l3 = ((pud_t *)(m2v(l4.pgd)))[l3idx];14571457- xen_raw_printk(" l3: %016lx\n", l3.pud);14581458- xen_raw_printk(" %016lx\n", pud_val(l3));14591459-14601460- l2 = ((pmd_t *)(m2v(l3.pud)))[l2idx];14611461- xen_raw_printk(" l2: %016lx\n", l2.pmd);14621462- xen_raw_printk(" %016lx\n", pmd_val(l2));14631463-14641464- l1 = ((pte_t *)(m2v(l2.pmd)))[l1idx];14651465- xen_raw_printk(" l1: %016lx\n", l1.pte);14661466- xen_raw_printk(" %016lx\n", pte_val(l1));14671467-}14681468-#endif14691469-14701480static void set_page_prot(void *addr, pgprot_t prot)14711481{14721482 unsigned long pfn = __pa(addr) >> PAGE_SHIFT;14731483 pte_t pte = pfn_pte(pfn, prot);14741474-14751475- xen_raw_printk("addr=%p pfn=%lx mfn=%lx prot=%016llx pte=%016llx\n",14761476- addr, pfn, get_phys_to_machine(pfn),14771477- pgprot_val(prot), pte.pte);1478148414791485 if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))14801486 BUG();···16141694 if (!xen_start_info)16151695 return;1616169616971697+ xen_domain_type = XEN_PV_DOMAIN;16981698+16171699 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);1618170016191701 xen_setup_features();···16251703 pv_init_ops = xen_init_ops;16261704 pv_time_ops = xen_time_ops;16271705 pv_cpu_ops = xen_cpu_ops;16281628- pv_irq_ops = xen_irq_ops;16291706 pv_apic_ops = xen_apic_ops;16301707 pv_mmu_ops = xen_mmu_ops;17081708+17091709+ xen_init_irq_ops();1631171016321711#ifdef CONFIG_X86_LOCAL_APIC16331712 /*···1660173716611738 /* Prevent unwanted bits from being set in PTEs. */16621739 __supported_pte_mask &= ~_PAGE_GLOBAL;16631663- if (!is_initial_xendomain())17401740+ if (!xen_initial_domain())16641741 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);1665174216661743 /* Don't do the full vcpu_info placement stuff until we have a···16951772 boot_params.hdr.ramdisk_size = xen_start_info->mod_len;16961773 boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line);1697177416981698- if (!is_initial_xendomain()) {17751775+ if (!xen_initial_domain()) {16991776 add_preferred_console("xenboot", 0, NULL);17001777 add_preferred_console("tty", 0, NULL);17011778 add_preferred_console("hvc", 0, NULL);17021779 }1703178017041781 xen_raw_console_write("about to get started...\n");17051705-17061706-#if 017071707- xen_raw_printk("&boot_params=%p __pa(&boot_params)=%lx __va(__pa(&boot_params))=%lx\n",17081708- &boot_params, __pa_symbol(&boot_params),17091709- __va(__pa_symbol(&boot_params)));17101710-17111711- walk(pgd, &boot_params);17121712- walk(pgd, __va(__pa(&boot_params)));17131713-#endif1714178217151783 /* Start the world */17161784#ifdef CONFIG_X86_32
+143
arch/x86/xen/irq.c
···11+#include <linux/hardirq.h>22+33+#include <xen/interface/xen.h>44+#include <xen/interface/sched.h>55+#include <xen/interface/vcpu.h>66+77+#include <asm/xen/hypercall.h>88+#include <asm/xen/hypervisor.h>99+1010+#include "xen-ops.h"1111+1212+/*1313+ * Force a proper event-channel callback from Xen after clearing the1414+ * callback mask. We do this in a very simple manner, by making a call1515+ * down into Xen. The pending flag will be checked by Xen on return.1616+ */1717+void xen_force_evtchn_callback(void)1818+{1919+ (void)HYPERVISOR_xen_version(0, NULL);2020+}2121+2222+static void __init __xen_init_IRQ(void)2323+{2424+#ifdef CONFIG_X86_642525+ int i;2626+2727+ /* Create identity vector->irq map */2828+ for(i = 0; i < NR_VECTORS; i++) {2929+ int cpu;3030+3131+ for_each_possible_cpu(cpu)3232+ per_cpu(vector_irq, cpu)[i] = i;3333+ }3434+#endif /* CONFIG_X86_64 */3535+3636+ xen_init_IRQ();3737+}3838+3939+static unsigned long xen_save_fl(void)4040+{4141+ struct vcpu_info *vcpu;4242+ unsigned long flags;4343+4444+ vcpu = x86_read_percpu(xen_vcpu);4545+4646+ /* flag has opposite sense of mask */4747+ flags = !vcpu->evtchn_upcall_mask;4848+4949+ /* convert to IF type flag5050+ -0 -> 0x000000005151+ -1 -> 0xffffffff5252+ */5353+ return (-flags) & X86_EFLAGS_IF;5454+}5555+5656+static void xen_restore_fl(unsigned long flags)5757+{5858+ struct vcpu_info *vcpu;5959+6060+ /* convert from IF type flag */6161+ flags = !(flags & X86_EFLAGS_IF);6262+6363+ /* There's a one instruction preempt window here. We need to6464+ make sure we're don't switch CPUs between getting the vcpu6565+ pointer and updating the mask. */6666+ preempt_disable();6767+ vcpu = x86_read_percpu(xen_vcpu);6868+ vcpu->evtchn_upcall_mask = flags;6969+ preempt_enable_no_resched();7070+7171+ /* Doesn't matter if we get preempted here, because any7272+ pending event will get dealt with anyway. */7373+7474+ if (flags == 0) {7575+ preempt_check_resched();7676+ barrier(); /* unmask then check (avoid races) */7777+ if (unlikely(vcpu->evtchn_upcall_pending))7878+ xen_force_evtchn_callback();7979+ }8080+}8181+8282+static void xen_irq_disable(void)8383+{8484+ /* There's a one instruction preempt window here. We need to8585+ make sure we're don't switch CPUs between getting the vcpu8686+ pointer and updating the mask. */8787+ preempt_disable();8888+ x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;8989+ preempt_enable_no_resched();9090+}9191+9292+static void xen_irq_enable(void)9393+{9494+ struct vcpu_info *vcpu;9595+9696+ /* We don't need to worry about being preempted here, since9797+ either a) interrupts are disabled, so no preemption, or b)9898+ the caller is confused and is trying to re-enable interrupts9999+ on an indeterminate processor. */100100+101101+ vcpu = x86_read_percpu(xen_vcpu);102102+ vcpu->evtchn_upcall_mask = 0;103103+104104+ /* Doesn't matter if we get preempted here, because any105105+ pending event will get dealt with anyway. */106106+107107+ barrier(); /* unmask then check (avoid races) */108108+ if (unlikely(vcpu->evtchn_upcall_pending))109109+ xen_force_evtchn_callback();110110+}111111+112112+static void xen_safe_halt(void)113113+{114114+ /* Blocking includes an implicit local_irq_enable(). */115115+ if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)116116+ BUG();117117+}118118+119119+static void xen_halt(void)120120+{121121+ if (irqs_disabled())122122+ HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);123123+ else124124+ xen_safe_halt();125125+}126126+127127+static const struct pv_irq_ops xen_irq_ops __initdata = {128128+ .init_IRQ = __xen_init_IRQ,129129+ .save_fl = xen_save_fl,130130+ .restore_fl = xen_restore_fl,131131+ .irq_disable = xen_irq_disable,132132+ .irq_enable = xen_irq_enable,133133+ .safe_halt = xen_safe_halt,134134+ .halt = xen_halt,135135+#ifdef CONFIG_X86_64136136+ .adjust_exception_frame = xen_adjust_exception_frame,137137+#endif138138+};139139+140140+void __init xen_init_irq_ops()141141+{142142+ pv_irq_ops = xen_irq_ops;143143+}
+263-51
arch/x86/xen/mmu.c
···4040 */4141#include <linux/sched.h>4242#include <linux/highmem.h>4343+#include <linux/debugfs.h>4344#include <linux/bug.h>44454546#include <asm/pgtable.h>···58575958#include "multicalls.h"6059#include "mmu.h"6060+#include "debugfs.h"6161+6262+#define MMU_UPDATE_HISTO 306363+6464+#ifdef CONFIG_XEN_DEBUG_FS6565+6666+static struct {6767+ u32 pgd_update;6868+ u32 pgd_update_pinned;6969+ u32 pgd_update_batched;7070+7171+ u32 pud_update;7272+ u32 pud_update_pinned;7373+ u32 pud_update_batched;7474+7575+ u32 pmd_update;7676+ u32 pmd_update_pinned;7777+ u32 pmd_update_batched;7878+7979+ u32 pte_update;8080+ u32 pte_update_pinned;8181+ u32 pte_update_batched;8282+8383+ u32 mmu_update;8484+ u32 mmu_update_extended;8585+ u32 mmu_update_histo[MMU_UPDATE_HISTO];8686+8787+ u32 prot_commit;8888+ u32 prot_commit_batched;8989+9090+ u32 set_pte_at;9191+ u32 set_pte_at_batched;9292+ u32 set_pte_at_pinned;9393+ u32 set_pte_at_current;9494+ u32 set_pte_at_kernel;9595+} mmu_stats;9696+9797+static u8 zero_stats;9898+9999+static inline void check_zero(void)100100+{101101+ if (unlikely(zero_stats)) {102102+ memset(&mmu_stats, 0, sizeof(mmu_stats));103103+ zero_stats = 0;104104+ }105105+}106106+107107+#define ADD_STATS(elem, val) \108108+ do { check_zero(); mmu_stats.elem += (val); } while(0)109109+110110+#else /* !CONFIG_XEN_DEBUG_FS */111111+112112+#define ADD_STATS(elem, val) do { (void)(val); } while(0)113113+114114+#endif /* CONFIG_XEN_DEBUG_FS */6111562116/*63117 * Just beyond the highest usermode address. STACK_TOP_MAX has a···285229}286230287231288288-static bool page_pinned(void *ptr)232232+static bool xen_page_pinned(void *ptr)289233{290234 struct page *page = virt_to_page(ptr);291235292236 return PagePinned(page);293237}294238295295-static void extend_mmu_update(const struct mmu_update *update)239239+static void xen_extend_mmu_update(const struct mmu_update *update)296240{297241 struct multicall_space mcs;298242 struct mmu_update *u;299243300244 mcs = xen_mc_extend_args(__HYPERVISOR_mmu_update, sizeof(*u));301245302302- if (mcs.mc != NULL)246246+ if (mcs.mc != NULL) {247247+ ADD_STATS(mmu_update_extended, 1);248248+ ADD_STATS(mmu_update_histo[mcs.mc->args[1]], -1);249249+303250 mcs.mc->args[1]++;304304- else {251251+252252+ if (mcs.mc->args[1] < MMU_UPDATE_HISTO)253253+ ADD_STATS(mmu_update_histo[mcs.mc->args[1]], 1);254254+ else255255+ ADD_STATS(mmu_update_histo[0], 1);256256+ } else {257257+ ADD_STATS(mmu_update, 1);305258 mcs = __xen_mc_entry(sizeof(*u));306259 MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, DOMID_SELF);260260+ ADD_STATS(mmu_update_histo[1], 1);307261 }308262309263 u = mcs.args;···331265 /* ptr may be ioremapped for 64-bit pagetable setup */332266 u.ptr = arbitrary_virt_to_machine(ptr).maddr;333267 u.val = pmd_val_ma(val);334334- extend_mmu_update(&u);268268+ xen_extend_mmu_update(&u);269269+270270+ ADD_STATS(pmd_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);335271336272 xen_mc_issue(PARAVIRT_LAZY_MMU);337273···342274343275void xen_set_pmd(pmd_t *ptr, pmd_t val)344276{277277+ ADD_STATS(pmd_update, 1);278278+345279 /* If page is not pinned, we can just update the entry346280 directly */347347- if (!page_pinned(ptr)) {281281+ if (!xen_page_pinned(ptr)) {348282 *ptr = val;349283 return;350284 }285285+286286+ ADD_STATS(pmd_update_pinned, 1);351287352288 xen_set_pmd_hyper(ptr, val);353289}···372300 if (mm == &init_mm)373301 preempt_disable();374302303303+ ADD_STATS(set_pte_at, 1);304304+// ADD_STATS(set_pte_at_pinned, xen_page_pinned(ptep));305305+ ADD_STATS(set_pte_at_current, mm == current->mm);306306+ ADD_STATS(set_pte_at_kernel, mm == &init_mm);307307+375308 if (mm == current->mm || mm == &init_mm) {376309 if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {377310 struct multicall_space mcs;378311 mcs = xen_mc_entry(0);379312380313 MULTI_update_va_mapping(mcs.mc, addr, pteval, 0);314314+ ADD_STATS(set_pte_at_batched, 1);381315 xen_mc_issue(PARAVIRT_LAZY_MMU);382316 goto out;383317 } else···412334413335 u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;414336 u.val = pte_val_ma(pte);415415- extend_mmu_update(&u);337337+ xen_extend_mmu_update(&u);338338+339339+ ADD_STATS(prot_commit, 1);340340+ ADD_STATS(prot_commit_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);416341417342 xen_mc_issue(PARAVIRT_LAZY_MMU);418343}···481400 /* ptr may be ioremapped for 64-bit pagetable setup */482401 u.ptr = arbitrary_virt_to_machine(ptr).maddr;483402 u.val = pud_val_ma(val);484484- extend_mmu_update(&u);403403+ xen_extend_mmu_update(&u);404404+405405+ ADD_STATS(pud_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);485406486407 xen_mc_issue(PARAVIRT_LAZY_MMU);487408···492409493410void xen_set_pud(pud_t *ptr, pud_t val)494411{412412+ ADD_STATS(pud_update, 1);413413+495414 /* If page is not pinned, we can just update the entry496415 directly */497497- if (!page_pinned(ptr)) {416416+ if (!xen_page_pinned(ptr)) {498417 *ptr = val;499418 return;500419 }420420+421421+ ADD_STATS(pud_update_pinned, 1);501422502423 xen_set_pud_hyper(ptr, val);503424}504425505426void xen_set_pte(pte_t *ptep, pte_t pte)506427{428428+ ADD_STATS(pte_update, 1);429429+// ADD_STATS(pte_update_pinned, xen_page_pinned(ptep));430430+ ADD_STATS(pte_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);431431+507432#ifdef CONFIG_X86_PAE508433 ptep->pte_high = pte.pte_high;509434 smp_wmb();···581490582491 u.ptr = virt_to_machine(ptr).maddr;583492 u.val = pgd_val_ma(val);584584- extend_mmu_update(&u);493493+ xen_extend_mmu_update(&u);585494}586495587496/*···608517{609518 pgd_t *user_ptr = xen_get_user_pgd(ptr);610519520520+ ADD_STATS(pgd_update, 1);521521+611522 /* If page is not pinned, we can just update the entry612523 directly */613613- if (!page_pinned(ptr)) {524524+ if (!xen_page_pinned(ptr)) {614525 *ptr = val;615526 if (user_ptr) {616616- WARN_ON(page_pinned(user_ptr));527527+ WARN_ON(xen_page_pinned(user_ptr));617528 *user_ptr = val;618529 }619530 return;620531 }532532+533533+ ADD_STATS(pgd_update_pinned, 1);534534+ ADD_STATS(pgd_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);621535622536 /* If it's pinned, then we can at least batch the kernel and623537 user updates together. */···651555 * For 64-bit, we must skip the Xen hole in the middle of the address652556 * space, just after the big x86-64 virtual hole.653557 */654654-static int pgd_walk(pgd_t *pgd, int (*func)(struct page *, enum pt_level),655655- unsigned long limit)558558+static int xen_pgd_walk(struct mm_struct *mm,559559+ int (*func)(struct mm_struct *mm, struct page *,560560+ enum pt_level),561561+ unsigned long limit)656562{563563+ pgd_t *pgd = mm->pgd;657564 int flush = 0;658565 unsigned hole_low, hole_high;659566 unsigned pgdidx_limit, pudidx_limit, pmdidx_limit;···689590 pmdidx_limit = 0;690591#endif691592692692- flush |= (*func)(virt_to_page(pgd), PT_PGD);693693-694593 for (pgdidx = 0; pgdidx <= pgdidx_limit; pgdidx++) {695594 pud_t *pud;696595···701604 pud = pud_offset(&pgd[pgdidx], 0);702605703606 if (PTRS_PER_PUD > 1) /* not folded */704704- flush |= (*func)(virt_to_page(pud), PT_PUD);607607+ flush |= (*func)(mm, virt_to_page(pud), PT_PUD);705608706609 for (pudidx = 0; pudidx < PTRS_PER_PUD; pudidx++) {707610 pmd_t *pmd;···716619 pmd = pmd_offset(&pud[pudidx], 0);717620718621 if (PTRS_PER_PMD > 1) /* not folded */719719- flush |= (*func)(virt_to_page(pmd), PT_PMD);622622+ flush |= (*func)(mm, virt_to_page(pmd), PT_PMD);720623721624 for (pmdidx = 0; pmdidx < PTRS_PER_PMD; pmdidx++) {722625 struct page *pte;···730633 continue;731634732635 pte = pmd_page(pmd[pmdidx]);733733- flush |= (*func)(pte, PT_PTE);636636+ flush |= (*func)(mm, pte, PT_PTE);734637 }735638 }736639 }640640+737641out:642642+ /* Do the top level last, so that the callbacks can use it as643643+ a cue to do final things like tlb flushes. */644644+ flush |= (*func)(mm, virt_to_page(pgd), PT_PGD);738645739646 return flush;740647}741648742742-static spinlock_t *lock_pte(struct page *page)649649+/* If we're using split pte locks, then take the page's lock and650650+ return a pointer to it. Otherwise return NULL. */651651+static spinlock_t *xen_pte_lock(struct page *page, struct mm_struct *mm)743652{744653 spinlock_t *ptl = NULL;745654746746-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS655655+#if USE_SPLIT_PTLOCKS747656 ptl = __pte_lockptr(page);748748- spin_lock(ptl);657657+ spin_lock_nest_lock(ptl, &mm->page_table_lock);749658#endif750659751660 return ptl;752661}753662754754-static void do_unlock(void *v)663663+static void xen_pte_unlock(void *v)755664{756665 spinlock_t *ptl = v;757666 spin_unlock(ptl);···775672 MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);776673}777674778778-static int pin_page(struct page *page, enum pt_level level)675675+static int xen_pin_page(struct mm_struct *mm, struct page *page,676676+ enum pt_level level)779677{780678 unsigned pgfl = TestSetPagePinned(page);781679 int flush;···795691796692 flush = 0;797693694694+ /*695695+ * We need to hold the pagetable lock between the time696696+ * we make the pagetable RO and when we actually pin697697+ * it. If we don't, then other users may come in and698698+ * attempt to update the pagetable by writing it,699699+ * which will fail because the memory is RO but not700700+ * pinned, so Xen won't do the trap'n'emulate.701701+ *702702+ * If we're using split pte locks, we can't hold the703703+ * entire pagetable's worth of locks during the704704+ * traverse, because we may wrap the preempt count (8705705+ * bits). The solution is to mark RO and pin each PTE706706+ * page while holding the lock. This means the number707707+ * of locks we end up holding is never more than a708708+ * batch size (~32 entries, at present).709709+ *710710+ * If we're not using split pte locks, we needn't pin711711+ * the PTE pages independently, because we're712712+ * protected by the overall pagetable lock.713713+ */798714 ptl = NULL;799715 if (level == PT_PTE)800800- ptl = lock_pte(page);716716+ ptl = xen_pte_lock(page, mm);801717802718 MULTI_update_va_mapping(mcs.mc, (unsigned long)pt,803719 pfn_pte(pfn, PAGE_KERNEL_RO),804720 level == PT_PGD ? UVMF_TLB_FLUSH : 0);805721806806- if (level == PT_PTE)722722+ if (ptl) {807723 xen_do_pin(MMUEXT_PIN_L1_TABLE, pfn);808724809809- if (ptl) {810725 /* Queue a deferred unlock for when this batch811726 is completed. */812812- xen_mc_callback(do_unlock, ptl);727727+ xen_mc_callback(xen_pte_unlock, ptl);813728 }814729 }815730···838715/* This is called just after a mm has been created, but it has not839716 been used yet. We need to make sure that its pagetable is all840717 read-only, and can be pinned. */841841-void xen_pgd_pin(pgd_t *pgd)718718+static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)842719{843720 xen_mc_batch();844721845845- if (pgd_walk(pgd, pin_page, USER_LIMIT)) {722722+ if (xen_pgd_walk(mm, xen_pin_page, USER_LIMIT)) {846723 /* re-enable interrupts for kmap_flush_unused */847724 xen_mc_issue(0);848725 kmap_flush_unused();···856733 xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(pgd)));857734858735 if (user_pgd) {859859- pin_page(virt_to_page(user_pgd), PT_PGD);736736+ xen_pin_page(mm, virt_to_page(user_pgd), PT_PGD);860737 xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(user_pgd)));861738 }862739 }863740#else /* CONFIG_X86_32 */864741#ifdef CONFIG_X86_PAE865742 /* Need to make sure unshared kernel PMD is pinnable */866866- pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);743743+ xen_pin_page(mm, virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])),744744+ PT_PMD);867745#endif868746 xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));869747#endif /* CONFIG_X86_64 */870748 xen_mc_issue(0);749749+}750750+751751+static void xen_pgd_pin(struct mm_struct *mm)752752+{753753+ __xen_pgd_pin(mm, mm->pgd);871754}872755873756/*···881752 * mfns turned into pfns. Search the list for any unpinned pgds and pin882753 * them (unpinned pgds are not currently in use, probably because the883754 * process is under construction or destruction).755755+ *756756+ * Expected to be called in stop_machine() ("equivalent to taking757757+ * every spinlock in the system"), so the locking doesn't really758758+ * matter all that much.884759 */885760void xen_mm_pin_all(void)886761{···895762896763 list_for_each_entry(page, &pgd_list, lru) {897764 if (!PagePinned(page)) {898898- xen_pgd_pin((pgd_t *)page_address(page));765765+ __xen_pgd_pin(&init_mm, (pgd_t *)page_address(page));899766 SetPageSavePinned(page);900767 }901768 }···908775 * that's before we have page structures to store the bits. So do all909776 * the book-keeping now.910777 */911911-static __init int mark_pinned(struct page *page, enum pt_level level)778778+static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page,779779+ enum pt_level level)912780{913781 SetPagePinned(page);914782 return 0;···917783918784void __init xen_mark_init_mm_pinned(void)919785{920920- pgd_walk(init_mm.pgd, mark_pinned, FIXADDR_TOP);786786+ xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP);921787}922788923923-static int unpin_page(struct page *page, enum pt_level level)789789+static int xen_unpin_page(struct mm_struct *mm, struct page *page,790790+ enum pt_level level)924791{925792 unsigned pgfl = TestClearPagePinned(page);926793···931796 spinlock_t *ptl = NULL;932797 struct multicall_space mcs;933798799799+ /*800800+ * Do the converse to pin_page. If we're using split801801+ * pte locks, we must be holding the lock for while802802+ * the pte page is unpinned but still RO to prevent803803+ * concurrent updates from seeing it in this804804+ * partially-pinned state.805805+ */934806 if (level == PT_PTE) {935935- ptl = lock_pte(page);807807+ ptl = xen_pte_lock(page, mm);936808937937- xen_do_pin(MMUEXT_UNPIN_TABLE, pfn);809809+ if (ptl)810810+ xen_do_pin(MMUEXT_UNPIN_TABLE, pfn);938811 }939812940813 mcs = __xen_mc_entry(0);···953810954811 if (ptl) {955812 /* unlock when batch completed */956956- xen_mc_callback(do_unlock, ptl);813813+ xen_mc_callback(xen_pte_unlock, ptl);957814 }958815 }959816···961818}962819963820/* Release a pagetables pages back as normal RW */964964-static void xen_pgd_unpin(pgd_t *pgd)821821+static void __xen_pgd_unpin(struct mm_struct *mm, pgd_t *pgd)965822{966823 xen_mc_batch();967824···973830974831 if (user_pgd) {975832 xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(user_pgd)));976976- unpin_page(virt_to_page(user_pgd), PT_PGD);833833+ xen_unpin_page(mm, virt_to_page(user_pgd), PT_PGD);977834 }978835 }979836#endif980837981838#ifdef CONFIG_X86_PAE982839 /* Need to make sure unshared kernel PMD is unpinned */983983- pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);840840+ xen_unpin_page(mm, virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])),841841+ PT_PMD);984842#endif985843986986- pgd_walk(pgd, unpin_page, USER_LIMIT);844844+ xen_pgd_walk(mm, xen_unpin_page, USER_LIMIT);987845988846 xen_mc_issue(0);847847+}848848+849849+static void xen_pgd_unpin(struct mm_struct *mm)850850+{851851+ __xen_pgd_unpin(mm, mm->pgd);989852}990853991854/*···1008859 list_for_each_entry(page, &pgd_list, lru) {1009860 if (PageSavePinned(page)) {1010861 BUG_ON(!PagePinned(page));10111011- xen_pgd_unpin((pgd_t *)page_address(page));862862+ __xen_pgd_unpin(&init_mm, (pgd_t *)page_address(page));1012863 ClearPageSavePinned(page);1013864 }1014865 }···1019870void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next)1020871{1021872 spin_lock(&next->page_table_lock);10221022- xen_pgd_pin(next->pgd);873873+ xen_pgd_pin(next);1023874 spin_unlock(&next->page_table_lock);1024875}10258761026877void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)1027878{1028879 spin_lock(&mm->page_table_lock);10291029- xen_pgd_pin(mm->pgd);880880+ xen_pgd_pin(mm);1030881 spin_unlock(&mm->page_table_lock);1031882}1032883···1056907 }1057908}105890910591059-static void drop_mm_ref(struct mm_struct *mm)910910+static void xen_drop_mm_ref(struct mm_struct *mm)1060911{1061912 cpumask_t mask;1062913 unsigned cpu;···1086937 smp_call_function_mask(mask, drop_other_mm_ref, mm, 1);1087938}1088939#else10891089-static void drop_mm_ref(struct mm_struct *mm)940940+static void xen_drop_mm_ref(struct mm_struct *mm)1090941{1091942 if (current->active_mm == mm)1092943 load_cr3(swapper_pg_dir);···1110961void xen_exit_mmap(struct mm_struct *mm)1111962{1112963 get_cpu(); /* make sure we don't move around */11131113- drop_mm_ref(mm);964964+ xen_drop_mm_ref(mm);1114965 put_cpu();11159661116967 spin_lock(&mm->page_table_lock);11179681118969 /* pgd may not be pinned in the error exit path of execve */11191119- if (page_pinned(mm->pgd))11201120- xen_pgd_unpin(mm->pgd);970970+ if (xen_page_pinned(mm->pgd))971971+ xen_pgd_unpin(mm);11219721122973 spin_unlock(&mm->page_table_lock);1123974}975975+976976+#ifdef CONFIG_XEN_DEBUG_FS977977+978978+static struct dentry *d_mmu_debug;979979+980980+static int __init xen_mmu_debugfs(void)981981+{982982+ struct dentry *d_xen = xen_init_debugfs();983983+984984+ if (d_xen == NULL)985985+ return -ENOMEM;986986+987987+ d_mmu_debug = debugfs_create_dir("mmu", d_xen);988988+989989+ debugfs_create_u8("zero_stats", 0644, d_mmu_debug, &zero_stats);990990+991991+ debugfs_create_u32("pgd_update", 0444, d_mmu_debug, &mmu_stats.pgd_update);992992+ debugfs_create_u32("pgd_update_pinned", 0444, d_mmu_debug,993993+ &mmu_stats.pgd_update_pinned);994994+ debugfs_create_u32("pgd_update_batched", 0444, d_mmu_debug,995995+ &mmu_stats.pgd_update_pinned);996996+997997+ debugfs_create_u32("pud_update", 0444, d_mmu_debug, &mmu_stats.pud_update);998998+ debugfs_create_u32("pud_update_pinned", 0444, d_mmu_debug,999999+ &mmu_stats.pud_update_pinned);10001000+ debugfs_create_u32("pud_update_batched", 0444, d_mmu_debug,10011001+ &mmu_stats.pud_update_pinned);10021002+10031003+ debugfs_create_u32("pmd_update", 0444, d_mmu_debug, &mmu_stats.pmd_update);10041004+ debugfs_create_u32("pmd_update_pinned", 0444, d_mmu_debug,10051005+ &mmu_stats.pmd_update_pinned);10061006+ debugfs_create_u32("pmd_update_batched", 0444, d_mmu_debug,10071007+ &mmu_stats.pmd_update_pinned);10081008+10091009+ debugfs_create_u32("pte_update", 0444, d_mmu_debug, &mmu_stats.pte_update);10101010+// debugfs_create_u32("pte_update_pinned", 0444, d_mmu_debug,10111011+// &mmu_stats.pte_update_pinned);10121012+ debugfs_create_u32("pte_update_batched", 0444, d_mmu_debug,10131013+ &mmu_stats.pte_update_pinned);10141014+10151015+ debugfs_create_u32("mmu_update", 0444, d_mmu_debug, &mmu_stats.mmu_update);10161016+ debugfs_create_u32("mmu_update_extended", 0444, d_mmu_debug,10171017+ &mmu_stats.mmu_update_extended);10181018+ xen_debugfs_create_u32_array("mmu_update_histo", 0444, d_mmu_debug,10191019+ mmu_stats.mmu_update_histo, 20);10201020+10211021+ debugfs_create_u32("set_pte_at", 0444, d_mmu_debug, &mmu_stats.set_pte_at);10221022+ debugfs_create_u32("set_pte_at_batched", 0444, d_mmu_debug,10231023+ &mmu_stats.set_pte_at_batched);10241024+ debugfs_create_u32("set_pte_at_current", 0444, d_mmu_debug,10251025+ &mmu_stats.set_pte_at_current);10261026+ debugfs_create_u32("set_pte_at_kernel", 0444, d_mmu_debug,10271027+ &mmu_stats.set_pte_at_kernel);10281028+10291029+ debugfs_create_u32("prot_commit", 0444, d_mmu_debug, &mmu_stats.prot_commit);10301030+ debugfs_create_u32("prot_commit_batched", 0444, d_mmu_debug,10311031+ &mmu_stats.prot_commit_batched);10321032+10331033+ return 0;10341034+}10351035+fs_initcall(xen_mmu_debugfs);10361036+10371037+#endif /* CONFIG_XEN_DEBUG_FS */
···298298 push %eax299299 push %ecx300300 push %edx301301- call force_evtchn_callback301301+ call xen_force_evtchn_callback302302 pop %edx303303 pop %ecx304304 pop %eax
+18-4
arch/x86/xen/xen-asm_64.S
···2626/* Pseudo-flag used for virtual NMI, which we don't implement yet */2727#define XEN_EFLAGS_NMI 0x8000000028282929-#if 03030-#include <asm/percpu.h>2929+#if 13030+/*3131+ x86-64 does not yet support direct access to percpu variables3232+ via a segment override, so we just need to make sure this code3333+ never gets used3434+ */3535+#define BUG ud2a3636+#define PER_CPU_VAR(var, off) 0xdeadbeef3737+#endif31383239/*3340 Enable events. This clears the event mask and tests the pending···4235 events, then enter the hypervisor to get them handled.4336 */4437ENTRY(xen_irq_enable_direct)3838+ BUG3939+4540 /* Unmask events */4641 movb $0, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)4742···6758 non-zero.6859 */6960ENTRY(xen_irq_disable_direct)6161+ BUG6262+7063 movb $1, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)7164ENDPATCH(xen_irq_disable_direct)7265 ret···8574 Xen and x86 use opposite senses (mask vs enable).8675 */8776ENTRY(xen_save_fl_direct)7777+ BUG7878+8879 testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)8980 setz %ah9081 addb %ah,%ah···10491 if so.10592 */10693ENTRY(xen_restore_fl_direct)9494+ BUG9595+10796 testb $X86_EFLAGS_IF>>8, %ah10897 setz PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)10998 /* Preempt here doesn't matter because that will deal with···137122 push %r9138123 push %r10139124 push %r11140140- call force_evtchn_callback125125+ call xen_force_evtchn_callback141126 pop %r11142127 pop %r10143128 pop %r9···148133 pop %rcx149134 pop %rax150135 ret151151-#endif152136153137ENTRY(xen_adjust_exception_frame)154138 mov 8+0(%rsp),%rcx
···108108{109109 struct hvc_struct *hp;110110111111- if (!is_running_on_xen() ||112112- is_initial_xendomain() ||111111+ if (!xen_pv_domain() ||112112+ xen_initial_domain() ||113113 !xen_start_info->console.domU.evtchn)114114 return -ENODEV;115115···142142143143static int xen_cons_init(void)144144{145145- if (!is_running_on_xen())145145+ if (!xen_pv_domain())146146 return 0;147147148148 hvc_instantiate(HVC_COOKIE, 0, &hvc_ops);
+2-2
drivers/input/xen-kbdfront.c
···335335336336static int __init xenkbd_init(void)337337{338338- if (!is_running_on_xen())338338+ if (!xen_domain())339339 return -ENODEV;340340341341 /* Nothing to do if running in dom0. */342342- if (is_initial_xendomain())342342+ if (xen_initial_domain())343343 return -ENODEV;344344345345 return xenbus_register_frontend(&xenkbd);
···210210211211/*-------------------------------------------------------------------------*/212212213213-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */214214-215215-/* Section 2.2 Host Controller Capability Registers */216216-struct ehci_caps {217217- /* these fields are specified as 8 and 16 bit registers,218218- * but some hosts can't perform 8 or 16 bit PCI accesses.219219- */220220- u32 hc_capbase;221221-#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */222222-#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */223223- u32 hcs_params; /* HCSPARAMS - offset 0x4 */224224-#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */225225-#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */226226-#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */227227-#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */228228-#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */229229-#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */230230-#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */231231-232232- u32 hcc_params; /* HCCPARAMS - offset 0x8 */233233-#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */234234-#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */235235-#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */236236-#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */237237-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/238238-#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */239239- u8 portroute [8]; /* nibbles for routing - offset 0xC */240240-} __attribute__ ((packed));241241-242242-243243-/* Section 2.3 Host Controller Operational Registers */244244-struct ehci_regs {245245-246246- /* USBCMD: offset 0x00 */247247- u32 command;248248-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */249249-#define CMD_PARK (1<<11) /* enable "park" on async qh */250250-#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */251251-#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */252252-#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */253253-#define CMD_ASE (1<<5) /* async schedule enable */254254-#define CMD_PSE (1<<4) /* periodic schedule enable */255255-/* 3:2 is periodic frame list size */256256-#define CMD_RESET (1<<1) /* reset HC not bus */257257-#define CMD_RUN (1<<0) /* start/stop HC */258258-259259- /* USBSTS: offset 0x04 */260260- u32 status;261261-#define STS_ASS (1<<15) /* Async Schedule Status */262262-#define STS_PSS (1<<14) /* Periodic Schedule Status */263263-#define STS_RECL (1<<13) /* Reclamation */264264-#define STS_HALT (1<<12) /* Not running (any reason) */265265-/* some bits reserved */266266- /* these STS_* flags are also intr_enable bits (USBINTR) */267267-#define STS_IAA (1<<5) /* Interrupted on async advance */268268-#define STS_FATAL (1<<4) /* such as some PCI access errors */269269-#define STS_FLR (1<<3) /* frame list rolled over */270270-#define STS_PCD (1<<2) /* port change detect */271271-#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */272272-#define STS_INT (1<<0) /* "normal" completion (short, ...) */273273-274274- /* USBINTR: offset 0x08 */275275- u32 intr_enable;276276-277277- /* FRINDEX: offset 0x0C */278278- u32 frame_index; /* current microframe number */279279- /* CTRLDSSEGMENT: offset 0x10 */280280- u32 segment; /* address bits 63:32 if needed */281281- /* PERIODICLISTBASE: offset 0x14 */282282- u32 frame_list; /* points to periodic list */283283- /* ASYNCLISTADDR: offset 0x18 */284284- u32 async_next; /* address of next async queue head */285285-286286- u32 reserved [9];287287-288288- /* CONFIGFLAG: offset 0x40 */289289- u32 configured_flag;290290-#define FLAG_CF (1<<0) /* true: we'll support "high speed" */291291-292292- /* PORTSC: offset 0x44 */293293- u32 port_status [0]; /* up to N_PORTS */294294-/* 31:23 reserved */295295-#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */296296-#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */297297-#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */298298-/* 19:16 for port testing */299299-#define PORT_LED_OFF (0<<14)300300-#define PORT_LED_AMBER (1<<14)301301-#define PORT_LED_GREEN (2<<14)302302-#define PORT_LED_MASK (3<<14)303303-#define PORT_OWNER (1<<13) /* true: companion hc owns this port */304304-#define PORT_POWER (1<<12) /* true: has power (see PPC) */305305-#define PORT_USB11(x) (((x)&(3<<10))==(1<<10)) /* USB 1.1 device */306306-/* 11:10 for detecting lowspeed devices (reset vs release ownership) */307307-/* 9 reserved */308308-#define PORT_RESET (1<<8) /* reset port */309309-#define PORT_SUSPEND (1<<7) /* suspend port */310310-#define PORT_RESUME (1<<6) /* resume it */311311-#define PORT_OCC (1<<5) /* over current change */312312-#define PORT_OC (1<<4) /* over current active */313313-#define PORT_PEC (1<<3) /* port enable change */314314-#define PORT_PE (1<<2) /* port enable */315315-#define PORT_CSC (1<<1) /* connect status change */316316-#define PORT_CONNECT (1<<0) /* device connected */317317-#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)318318-} __attribute__ ((packed));319319-320320-#define USBMODE 0x68 /* USB Device mode */321321-#define USBMODE_SDIS (1<<3) /* Stream disable */322322-#define USBMODE_BE (1<<2) /* BE/LE endianness select */323323-#define USBMODE_CM_HC (3<<0) /* host controller mode */324324-#define USBMODE_CM_IDLE (0<<0) /* idle state */325325-326326-/* Appendix C, Debug port ... intended for use with special "debug devices"327327- * that can help if there's no serial console. (nonstandard enumeration.)328328- */329329-struct ehci_dbg_port {330330- u32 control;331331-#define DBGP_OWNER (1<<30)332332-#define DBGP_ENABLED (1<<28)333333-#define DBGP_DONE (1<<16)334334-#define DBGP_INUSE (1<<10)335335-#define DBGP_ERRCODE(x) (((x)>>7)&0x07)336336-# define DBGP_ERR_BAD 1337337-# define DBGP_ERR_SIGNAL 2338338-#define DBGP_ERROR (1<<6)339339-#define DBGP_GO (1<<5)340340-#define DBGP_OUT (1<<4)341341-#define DBGP_LEN(x) (((x)>>0)&0x0f)342342- u32 pids;343343-#define DBGP_PID_GET(x) (((x)>>16)&0xff)344344-#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok))345345- u32 data03;346346- u32 data47;347347- u32 address;348348-#define DBGP_EPADDR(dev,ep) (((dev)<<8)|(ep))349349-} __attribute__ ((packed));213213+#include <linux/usb/ehci_def.h>350214351215/*-------------------------------------------------------------------------*/352216
-2
drivers/video/Kconfig
···673673 select FB_CFB_FILLRECT674674 select FB_CFB_COPYAREA675675 select FB_CFB_IMAGEBLIT676676- select VIDEO_SELECT677676 help678677 This is the frame buffer device driver for generic VESA 2.0679678 compliant graphic cards. The older VESA 1.2 cards are not supported.···15771578 tristate "Cyberblade/i1 support"15781579 depends on FB && PCI && X86_32 && !64BIT15791580 select FB_CFB_IMAGEBLIT15801580- select VIDEO_SELECT15811581 ---help---15821582 This driver is supposed to support the Trident Cyberblade/i115831583 graphics core integrated in the VIA VT8601A North Bridge,
-16
drivers/video/console/Kconfig
···4343 buffer. Each 64KB will give you approximately 16 80x254444 screenfuls of scrollback buffer45454646-config VIDEO_SELECT4747- bool "Video mode selection support"4848- depends on X86 && VGA_CONSOLE4949- ---help---5050- This enables support for text mode selection on kernel startup. If5151- you want to take advantage of some high-resolution text mode your5252- card's BIOS offers, but the traditional Linux utilities like5353- SVGATextMode don't, you can say Y here and set the mode using the5454- "vga=" option from your boot loader (lilo or loadlin) or set5555- "vga=ask" which brings up a video mode menu on kernel startup. (Try5656- "man bootparam" or see the documentation of your boot loader about5757- how to pass options to the kernel.)5858-5959- Read the file <file:Documentation/svga.txt> for more information6060- about the Video mode selection support. If unsure, say N.6161-6246config MDA_CONSOLE6347 depends on !M68K && !PARISC && ISA6448 tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
+2-2
drivers/video/xen-fbfront.c
···680680681681static int __init xenfb_init(void)682682{683683- if (!is_running_on_xen())683683+ if (!xen_domain())684684 return -ENODEV;685685686686 /* Nothing to do if running in dom0. */687687- if (is_initial_xendomain())687687+ if (xen_initial_domain())688688 return -ENODEV;689689690690 return xenbus_register_frontend(&xenfb);
···5353#include <asm/tlb.h>54545555#include <xen/interface/memory.h>5656-#include <xen/balloon.h>5756#include <xen/xenbus.h>5857#include <xen/features.h>5958#include <xen/page.h>···225226 }226227227228 set_xen_guest_handle(reservation.extent_start, frame_list);228228- reservation.nr_extents = nr_pages;229229- rc = HYPERVISOR_memory_op(230230- XENMEM_populate_physmap, &reservation);229229+ reservation.nr_extents = nr_pages;230230+ rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);231231 if (rc < nr_pages) {232232 if (rc > 0) {233233 int ret;···234236 /* We hit the Xen hard limit: reprobe. */235237 reservation.nr_extents = rc;236238 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,237237- &reservation);239239+ &reservation);238240 BUG_ON(ret != rc);239241 }240242 if (rc >= 0)···418420 unsigned long pfn;419421 struct page *page;420422421421- if (!is_running_on_xen())423423+ if (!xen_pv_domain())422424 return -ENODEV;423425424426 pr_info("xen_balloon: Initialising balloon driver.\n");···462464463465module_exit(balloon_exit);464466465465-static void balloon_update_driver_allowance(long delta)466466-{467467- unsigned long flags;468468-469469- spin_lock_irqsave(&balloon_lock, flags);470470- balloon_stats.driver_pages += delta;471471- spin_unlock_irqrestore(&balloon_lock, flags);472472-}473473-474474-static int dealloc_pte_fn(475475- pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)476476-{477477- unsigned long mfn = pte_mfn(*pte);478478- int ret;479479- struct xen_memory_reservation reservation = {480480- .nr_extents = 1,481481- .extent_order = 0,482482- .domid = DOMID_SELF483483- };484484- set_xen_guest_handle(reservation.extent_start, &mfn);485485- set_pte_at(&init_mm, addr, pte, __pte_ma(0ull));486486- set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);487487- ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);488488- BUG_ON(ret != 1);489489- return 0;490490-}491491-492492-static struct page **alloc_empty_pages_and_pagevec(int nr_pages)493493-{494494- unsigned long vaddr, flags;495495- struct page *page, **pagevec;496496- int i, ret;497497-498498- pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);499499- if (pagevec == NULL)500500- return NULL;501501-502502- for (i = 0; i < nr_pages; i++) {503503- page = pagevec[i] = alloc_page(GFP_KERNEL);504504- if (page == NULL)505505- goto err;506506-507507- vaddr = (unsigned long)page_address(page);508508-509509- scrub_page(page);510510-511511- spin_lock_irqsave(&balloon_lock, flags);512512-513513- if (xen_feature(XENFEAT_auto_translated_physmap)) {514514- unsigned long gmfn = page_to_pfn(page);515515- struct xen_memory_reservation reservation = {516516- .nr_extents = 1,517517- .extent_order = 0,518518- .domid = DOMID_SELF519519- };520520- set_xen_guest_handle(reservation.extent_start, &gmfn);521521- ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,522522- &reservation);523523- if (ret == 1)524524- ret = 0; /* success */525525- } else {526526- ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,527527- dealloc_pte_fn, NULL);528528- }529529-530530- if (ret != 0) {531531- spin_unlock_irqrestore(&balloon_lock, flags);532532- __free_page(page);533533- goto err;534534- }535535-536536- totalram_pages = --balloon_stats.current_pages;537537-538538- spin_unlock_irqrestore(&balloon_lock, flags);539539- }540540-541541- out:542542- schedule_work(&balloon_worker);543543- flush_tlb_all();544544- return pagevec;545545-546546- err:547547- spin_lock_irqsave(&balloon_lock, flags);548548- while (--i >= 0)549549- balloon_append(pagevec[i]);550550- spin_unlock_irqrestore(&balloon_lock, flags);551551- kfree(pagevec);552552- pagevec = NULL;553553- goto out;554554-}555555-556556-static void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)557557-{558558- unsigned long flags;559559- int i;560560-561561- if (pagevec == NULL)562562- return;563563-564564- spin_lock_irqsave(&balloon_lock, flags);565565- for (i = 0; i < nr_pages; i++) {566566- BUG_ON(page_count(pagevec[i]) != 1);567567- balloon_append(pagevec[i]);568568- }569569- spin_unlock_irqrestore(&balloon_lock, flags);570570-571571- kfree(pagevec);572572-573573- schedule_work(&balloon_worker);574574-}575575-576576-static void balloon_release_driver_page(struct page *page)577577-{578578- unsigned long flags;579579-580580- spin_lock_irqsave(&balloon_lock, flags);581581- balloon_append(page);582582- balloon_stats.driver_pages--;583583- spin_unlock_irqrestore(&balloon_lock, flags);584584-585585- schedule_work(&balloon_worker);586586-}587587-588588-589589-#define BALLOON_SHOW(name, format, args...) \590590- static ssize_t show_##name(struct sys_device *dev, \591591- char *buf) \592592- { \593593- return sprintf(buf, format, ##args); \594594- } \467467+#define BALLOON_SHOW(name, format, args...) \468468+ static ssize_t show_##name(struct sys_device *dev, \469469+ struct sysdev_attribute *attr, \470470+ char *buf) \471471+ { \472472+ return sprintf(buf, format, ##args); \473473+ } \595474 static SYSDEV_ATTR(name, S_IRUGO, show_##name, NULL)596475597476BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));···479604 (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0);480605BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));481606482482-static ssize_t show_target_kb(struct sys_device *dev, char *buf)607607+static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr,608608+ char *buf)483609{484610 return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages));485611}···490614 const char *buf,491615 size_t count)492616{493493- char memstring[64], *endchar;617617+ char *endchar;494618 unsigned long long target_bytes;495619496620 if (!capable(CAP_SYS_ADMIN))497621 return -EPERM;498622499499- if (count <= 1)500500- return -EBADMSG; /* runt */501501- if (count > sizeof(memstring))502502- return -EFBIG; /* too long */503503- strcpy(memstring, buf);623623+ target_bytes = memparse(buf, &endchar);504624505505- target_bytes = memparse(memstring, &endchar);506625 balloon_set_new_target(target_bytes >> PAGE_SHIFT);507626508627 return count;···563692 sysdev_unregister(sysdev);564693 sysdev_class_unregister(&balloon_sysdev_class);565694 return error;566566-}567567-568568-static void unregister_balloon(struct sys_device *sysdev)569569-{570570- int i;571571-572572- sysfs_remove_group(&sysdev->kobj, &balloon_info_group);573573- for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++)574574- sysdev_remove_file(sysdev, balloon_attrs[i]);575575- sysdev_unregister(sysdev);576576- sysdev_class_unregister(&balloon_sysdev_class);577577-}578578-579579-static void balloon_sysfs_exit(void)580580-{581581- unregister_balloon(&balloon_sysdev);582695}583696584697MODULE_LICENSE("GPL");
+90
drivers/xen/cpu_hotplug.c
···11+#include <linux/notifier.h>22+33+#include <xen/xenbus.h>44+55+#include <asm-x86/xen/hypervisor.h>66+#include <asm/cpu.h>77+88+static void enable_hotplug_cpu(int cpu)99+{1010+ if (!cpu_present(cpu))1111+ arch_register_cpu(cpu);1212+1313+ cpu_set(cpu, cpu_present_map);1414+}1515+1616+static void disable_hotplug_cpu(int cpu)1717+{1818+ if (cpu_present(cpu))1919+ arch_unregister_cpu(cpu);2020+2121+ cpu_clear(cpu, cpu_present_map);2222+}2323+2424+static void vcpu_hotplug(unsigned int cpu)2525+{2626+ int err;2727+ char dir[32], state[32];2828+2929+ if (!cpu_possible(cpu))3030+ return;3131+3232+ sprintf(dir, "cpu/%u", cpu);3333+ err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);3434+ if (err != 1) {3535+ printk(KERN_ERR "XENBUS: Unable to read cpu state\n");3636+ return;3737+ }3838+3939+ if (strcmp(state, "online") == 0) {4040+ enable_hotplug_cpu(cpu);4141+ } else if (strcmp(state, "offline") == 0) {4242+ (void)cpu_down(cpu);4343+ disable_hotplug_cpu(cpu);4444+ } else {4545+ printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",4646+ state, cpu);4747+ }4848+}4949+5050+static void handle_vcpu_hotplug_event(struct xenbus_watch *watch,5151+ const char **vec, unsigned int len)5252+{5353+ unsigned int cpu;5454+ char *cpustr;5555+ const char *node = vec[XS_WATCH_PATH];5656+5757+ cpustr = strstr(node, "cpu/");5858+ if (cpustr != NULL) {5959+ sscanf(cpustr, "cpu/%u", &cpu);6060+ vcpu_hotplug(cpu);6161+ }6262+}6363+6464+static int setup_cpu_watcher(struct notifier_block *notifier,6565+ unsigned long event, void *data)6666+{6767+ static struct xenbus_watch cpu_watch = {6868+ .node = "cpu",6969+ .callback = handle_vcpu_hotplug_event};7070+7171+ (void)register_xenbus_watch(&cpu_watch);7272+7373+ return NOTIFY_DONE;7474+}7575+7676+static int __init setup_vcpu_hotplug_event(void)7777+{7878+ static struct notifier_block xsn_cpu = {7979+ .notifier_call = setup_cpu_watcher };8080+8181+ if (!xen_pv_domain())8282+ return -ENODEV;8383+8484+ register_xenstore_notifier(&xsn_cpu);8585+8686+ return 0;8787+}8888+8989+arch_initcall(setup_vcpu_hotplug_event);9090+
+29-11
drivers/xen/events.c
···8484/* Xen will never allocate port zero for any purpose. */8585#define VALID_EVTCHN(chn) ((chn) != 0)86868787-/*8888- * Force a proper event-channel callback from Xen after clearing the8989- * callback mask. We do this in a very simple manner, by making a call9090- * down into Xen. The pending flag will be checked by Xen on return.9191- */9292-void force_evtchn_callback(void)9393-{9494- (void)HYPERVISOR_xen_version(0, NULL);9595-}9696-EXPORT_SYMBOL_GPL(force_evtchn_callback);9797-9887static struct irq_chip xen_dynamic_chip;998810089/* Constructor for packed IRQ information. */···162173{163174 struct shared_info *s = HYPERVISOR_shared_info;164175 sync_set_bit(port, &s->evtchn_pending[0]);176176+}177177+178178+static inline int test_evtchn(int port)179179+{180180+ struct shared_info *s = HYPERVISOR_shared_info;181181+ return sync_test_bit(port, &s->evtchn_pending[0]);165182}166183167184···358363 switch (type_from_irq(irq)) {359364 case IRQT_VIRQ:360365 per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))366366+ [index_from_irq(irq)] = -1;367367+ break;368368+ case IRQT_IPI:369369+ per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))361370 [index_from_irq(irq)] = -1;362371 break;363372 default:···740741741742 if (VALID_EVTCHN(evtchn))742743 clear_evtchn(evtchn);744744+}745745+746746+void xen_set_irq_pending(int irq)747747+{748748+ int evtchn = evtchn_from_irq(irq);749749+750750+ if (VALID_EVTCHN(evtchn))751751+ set_evtchn(evtchn);752752+}753753+754754+bool xen_test_irq_pending(int irq)755755+{756756+ int evtchn = evtchn_from_irq(irq);757757+ bool ret = false;758758+759759+ if (VALID_EVTCHN(evtchn))760760+ ret = test_evtchn(evtchn);761761+762762+ return ret;743763}744764745765/* Poll waiting for an irq to become pending. In the usual case, the
+1-1
drivers/xen/grant-table.c
···508508 unsigned int max_nr_glist_frames, nr_glist_frames;509509 unsigned int nr_init_grefs;510510511511- if (!is_running_on_xen())511511+ if (!xen_domain())512512 return -ENODEV;513513514514 nr_grant_frames = 1;
+4-4
drivers/xen/xenbus/xenbus_probe.c
···814814 DPRINTK("");815815816816 err = -ENODEV;817817- if (!is_running_on_xen())817817+ if (!xen_domain())818818 goto out_error;819819820820 /* Register ourselves with the kernel bus subsystem */···829829 /*830830 * Domain0 doesn't have a store_evtchn or store_mfn yet.831831 */832832- if (is_initial_xendomain()) {832832+ if (xen_initial_domain()) {833833 /* dom0 not yet supported */834834 } else {835835 xenstored_ready = 1;···846846 goto out_unreg_back;847847 }848848849849- if (!is_initial_xendomain())849849+ if (!xen_initial_domain())850850 xenbus_probe(NULL);851851852852 return 0;···937937 unsigned long timeout = jiffies + 10*HZ;938938 struct device_driver *drv = xendrv ? &xendrv->driver : NULL;939939940940- if (!ready_to_wait_for_devices || !is_running_on_xen())940940+ if (!ready_to_wait_for_devices || !xen_domain())941941 return;942942943943 while (exists_disconnected_device(drv)) {
+2
include/asm-generic/siginfo.h
···199199 */200200#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */201201#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */202202+#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */203203+#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */202204#define NSIGTRAP 2203205204206/*
-5
include/asm-parisc/siginfo.h
···3344#include <asm-generic/siginfo.h>5566-/*77- * SIGTRAP si_codes88- */99-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */1010-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */116#undef NSIGTRAP127#define NSIGTRAP 4138
+17
include/asm-x86/bios_ebda.h
···16161717void reserve_ebda_region(void);18181919+#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION2020+/*2121+ * This is obviously not a great place for this, but we want to be2222+ * able to scatter it around anywhere in the kernel.2323+ */2424+void check_for_bios_corruption(void);2525+void start_periodic_check_for_corruption(void);2626+#else2727+static inline void check_for_bios_corruption(void)2828+{2929+}3030+3131+static inline void start_periodic_check_for_corruption(void)3232+{3333+}3434+#endif3535+1936#endif /* ASM_X86__BIOS_EBDA_H */
···586586 write_cr4(cr4);587587}588588589589-struct microcode_header {590590- unsigned int hdrver;591591- unsigned int rev;592592- unsigned int date;593593- unsigned int sig;594594- unsigned int cksum;595595- unsigned int ldrver;596596- unsigned int pf;597597- unsigned int datasize;598598- unsigned int totalsize;599599- unsigned int reserved[3];600600-};601601-602602-struct microcode {603603- struct microcode_header hdr;604604- unsigned int bits[0];605605-};606606-607607-typedef struct microcode microcode_t;608608-typedef struct microcode_header microcode_header_t;609609-610610-/* microcode format is extended from prescott processors */611611-struct extended_signature {612612- unsigned int sig;613613- unsigned int pf;614614- unsigned int cksum;615615-};616616-617617-struct extended_sigtable {618618- unsigned int count;619619- unsigned int cksum;620620- unsigned int reserved[3];621621- struct extended_signature sigs[0];622622-};623623-624589typedef struct {625590 unsigned long seg;626591} mm_segment_t;
+3-3
include/asm-x86/ptrace.h
···177177178178#ifdef CONFIG_X86_32179179extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,180180- int error_code);181181-#else182182-void signal_fault(struct pt_regs *regs, void __user *frame, char *where);180180+ int error_code, int si_code);183181#endif182182+183183+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);184184185185extern long syscall_trace_enter(struct pt_regs *);186186extern void syscall_trace_leave(struct pt_regs *);
+26-8
include/asm-x86/smp.h
···5050struct smp_ops {5151 void (*smp_prepare_boot_cpu)(void);5252 void (*smp_prepare_cpus)(unsigned max_cpus);5353- int (*cpu_up)(unsigned cpu);5453 void (*smp_cpus_done)(unsigned max_cpus);55545655 void (*smp_send_stop)(void);5756 void (*smp_send_reschedule)(int cpu);5757+5858+ int (*cpu_up)(unsigned cpu);5959+ int (*cpu_disable)(void);6060+ void (*cpu_die)(unsigned int cpu);6161+ void (*play_dead)(void);58625963 void (*send_call_func_ipi)(cpumask_t mask);6064 void (*send_call_func_single_ipi)(int cpu);···9894 return smp_ops.cpu_up(cpu);9995}100969797+static inline int __cpu_disable(void)9898+{9999+ return smp_ops.cpu_disable();100100+}101101+102102+static inline void __cpu_die(unsigned int cpu)103103+{104104+ smp_ops.cpu_die(cpu);105105+}106106+107107+static inline void play_dead(void)108108+{109109+ smp_ops.play_dead();110110+}111111+101112static inline void smp_send_reschedule(int cpu)102113{103114 smp_ops.smp_send_reschedule(cpu);···128109 smp_ops.send_call_func_ipi(mask);129110}130111112112+void cpu_disable_common(void);131113void native_smp_prepare_boot_cpu(void);132114void native_smp_prepare_cpus(unsigned int max_cpus);133115void native_smp_cpus_done(unsigned int max_cpus);134116int native_cpu_up(unsigned int cpunum);117117+int native_cpu_disable(void);118118+void native_cpu_die(unsigned int cpu);119119+void native_play_dead(void);120120+void play_dead_common(void);121121+135122void native_send_call_func_ipi(cpumask_t mask);136123void native_send_call_func_single_ipi(int cpu);137137-138138-extern int __cpu_disable(void);139139-extern void __cpu_die(unsigned int cpu);140124141125void smp_store_cpu_info(int id);142126#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)···226204# endif227205228206#endif /* CONFIG_X86_LOCAL_APIC */229229-230230-#ifdef CONFIG_HOTPLUG_CPU231231-extern void cpu_uninit(void);232232-#endif233207234208#endif /* __ASSEMBLY__ */235209#endif /* ASM_X86__SMP_H */
···182182183183extern int get_option(char **str, int *pint);184184extern char *get_options(const char *str, int nints, int *ints);185185-extern unsigned long long memparse(char *ptr, char **retptr);185185+extern unsigned long long memparse(const char *ptr, char **retptr);186186187187extern int core_kernel_text(unsigned long addr);188188extern int __kernel_text_address(unsigned long addr);
+4-9
include/linux/mm.h
···7788#include <linux/gfp.h>99#include <linux/list.h>1010+#include <linux/mmdebug.h>1011#include <linux/mmzone.h>1112#include <linux/rbtree.h>1213#include <linux/prio_tree.h>···219218 * files which need it (119 of them)220219 */221220#include <linux/page-flags.h>222222-223223-#ifdef CONFIG_DEBUG_VM224224-#define VM_BUG_ON(cond) BUG_ON(cond)225225-#else226226-#define VM_BUG_ON(condition) do { } while(0)227227-#endif228221229222/*230223 * Methods to modify the page usage count.···914919}915920#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */916921917917-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS922922+#if USE_SPLIT_PTLOCKS918923/*919924 * We tuck a spinlock to guard each pagetable page into its struct page,920925 * at page->private, with BUILD_BUG_ON to make sure that this will not···927932} while (0)928933#define pte_lock_deinit(page) ((page)->mapping = NULL)929934#define pte_lockptr(mm, pmd) ({(void)(mm); __pte_lockptr(pmd_page(*(pmd)));})930930-#else935935+#else /* !USE_SPLIT_PTLOCKS */931936/*932937 * We use mm->page_table_lock to guard all pagetable pages of the mm.933938 */934939#define pte_lock_init(page) do {} while (0)935940#define pte_lock_deinit(page) do {} while (0)936941#define pte_lockptr(mm, pmd) ({(void)(pmd); &(mm)->page_table_lock;})937937-#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */942942+#endif /* USE_SPLIT_PTLOCKS */938943939944static inline void pgtable_page_ctor(struct page *page)940945{
+6-4
include/linux/mm_types.h
···21212222struct address_space;23232424-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS2424+#define USE_SPLIT_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)2525+2626+#if USE_SPLIT_PTLOCKS2527typedef atomic_long_t mm_counter_t;2626-#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */2828+#else /* !USE_SPLIT_PTLOCKS */2729typedef unsigned long mm_counter_t;2828-#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */3030+#endif /* !USE_SPLIT_PTLOCKS */29313032/*3133 * Each physical page in the system has a struct page associated with···6765 * see PAGE_MAPPING_ANON below.6866 */6967 };7070-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS6868+#if USE_SPLIT_PTLOCKS7169 spinlock_t ptl;7270#endif7371 struct kmem_cache *slab; /* SLUB: Pointer to slab */
+18
include/linux/mmdebug.h
···11+#ifndef LINUX_MM_DEBUG_H22+#define LINUX_MM_DEBUG_H 133+44+#include <linux/autoconf.h>55+66+#ifdef CONFIG_DEBUG_VM77+#define VM_BUG_ON(cond) BUG_ON(cond)88+#else99+#define VM_BUG_ON(cond) do { } while (0)1010+#endif1111+1212+#ifdef CONFIG_DEBUG_VIRTUAL1313+#define VIRTUAL_BUG_ON(cond) BUG_ON(cond)1414+#else1515+#define VIRTUAL_BUG_ON(cond) do { } while (0)1616+#endif1717+1818+#endif
+3-3
include/linux/sched.h
···352352extern void arch_unmap_area(struct mm_struct *, unsigned long);353353extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);354354355355-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS355355+#if USE_SPLIT_PTLOCKS356356/*357357 * The mm counters are not protected by its page_table_lock,358358 * so must be incremented atomically.···363363#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)364364#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)365365366366-#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */366366+#else /* !USE_SPLIT_PTLOCKS */367367/*368368 * The mm counters are protected by its page_table_lock,369369 * so can be incremented directly.···374374#define inc_mm_counter(mm, member) (mm)->_##member++375375#define dec_mm_counter(mm, member) (mm)->_##member--376376377377-#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */377377+#endif /* !USE_SPLIT_PTLOCKS */378378379379#define get_mm_rss(mm) \380380 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
+160
include/linux/usb/ehci_def.h
···11+/*22+ * Copyright (c) 2001-2002 by David Brownell33+ *44+ * This program is free software; you can redistribute it and/or modify it55+ * under the terms of the GNU General Public License as published by the66+ * Free Software Foundation; either version 2 of the License, or (at your77+ * option) any later version.88+ *99+ * This program is distributed in the hope that it will be useful, but1010+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY1111+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License1212+ * for more details.1313+ *1414+ * You should have received a copy of the GNU General Public License1515+ * along with this program; if not, write to the Free Software Foundation,1616+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.1717+ */1818+1919+#ifndef __LINUX_USB_EHCI_DEF_H2020+#define __LINUX_USB_EHCI_DEF_H2121+2222+/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */2323+2424+/* Section 2.2 Host Controller Capability Registers */2525+struct ehci_caps {2626+ /* these fields are specified as 8 and 16 bit registers,2727+ * but some hosts can't perform 8 or 16 bit PCI accesses.2828+ */2929+ u32 hc_capbase;3030+#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */3131+#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */3232+ u32 hcs_params; /* HCSPARAMS - offset 0x4 */3333+#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */3434+#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */3535+#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */3636+#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */3737+#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */3838+#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */3939+#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */4040+4141+ u32 hcc_params; /* HCCPARAMS - offset 0x8 */4242+#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */4343+#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */4444+#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */4545+#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */4646+#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/4747+#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */4848+ u8 portroute [8]; /* nibbles for routing - offset 0xC */4949+} __attribute__ ((packed));5050+5151+5252+/* Section 2.3 Host Controller Operational Registers */5353+struct ehci_regs {5454+5555+ /* USBCMD: offset 0x00 */5656+ u32 command;5757+/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */5858+#define CMD_PARK (1<<11) /* enable "park" on async qh */5959+#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */6060+#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */6161+#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */6262+#define CMD_ASE (1<<5) /* async schedule enable */6363+#define CMD_PSE (1<<4) /* periodic schedule enable */6464+/* 3:2 is periodic frame list size */6565+#define CMD_RESET (1<<1) /* reset HC not bus */6666+#define CMD_RUN (1<<0) /* start/stop HC */6767+6868+ /* USBSTS: offset 0x04 */6969+ u32 status;7070+#define STS_ASS (1<<15) /* Async Schedule Status */7171+#define STS_PSS (1<<14) /* Periodic Schedule Status */7272+#define STS_RECL (1<<13) /* Reclamation */7373+#define STS_HALT (1<<12) /* Not running (any reason) */7474+/* some bits reserved */7575+ /* these STS_* flags are also intr_enable bits (USBINTR) */7676+#define STS_IAA (1<<5) /* Interrupted on async advance */7777+#define STS_FATAL (1<<4) /* such as some PCI access errors */7878+#define STS_FLR (1<<3) /* frame list rolled over */7979+#define STS_PCD (1<<2) /* port change detect */8080+#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */8181+#define STS_INT (1<<0) /* "normal" completion (short, ...) */8282+8383+ /* USBINTR: offset 0x08 */8484+ u32 intr_enable;8585+8686+ /* FRINDEX: offset 0x0C */8787+ u32 frame_index; /* current microframe number */8888+ /* CTRLDSSEGMENT: offset 0x10 */8989+ u32 segment; /* address bits 63:32 if needed */9090+ /* PERIODICLISTBASE: offset 0x14 */9191+ u32 frame_list; /* points to periodic list */9292+ /* ASYNCLISTADDR: offset 0x18 */9393+ u32 async_next; /* address of next async queue head */9494+9595+ u32 reserved [9];9696+9797+ /* CONFIGFLAG: offset 0x40 */9898+ u32 configured_flag;9999+#define FLAG_CF (1<<0) /* true: we'll support "high speed" */100100+101101+ /* PORTSC: offset 0x44 */102102+ u32 port_status [0]; /* up to N_PORTS */103103+/* 31:23 reserved */104104+#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */105105+#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */106106+#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */107107+/* 19:16 for port testing */108108+#define PORT_LED_OFF (0<<14)109109+#define PORT_LED_AMBER (1<<14)110110+#define PORT_LED_GREEN (2<<14)111111+#define PORT_LED_MASK (3<<14)112112+#define PORT_OWNER (1<<13) /* true: companion hc owns this port */113113+#define PORT_POWER (1<<12) /* true: has power (see PPC) */114114+#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */115115+/* 11:10 for detecting lowspeed devices (reset vs release ownership) */116116+/* 9 reserved */117117+#define PORT_RESET (1<<8) /* reset port */118118+#define PORT_SUSPEND (1<<7) /* suspend port */119119+#define PORT_RESUME (1<<6) /* resume it */120120+#define PORT_OCC (1<<5) /* over current change */121121+#define PORT_OC (1<<4) /* over current active */122122+#define PORT_PEC (1<<3) /* port enable change */123123+#define PORT_PE (1<<2) /* port enable */124124+#define PORT_CSC (1<<1) /* connect status change */125125+#define PORT_CONNECT (1<<0) /* device connected */126126+#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)127127+} __attribute__ ((packed));128128+129129+#define USBMODE 0x68 /* USB Device mode */130130+#define USBMODE_SDIS (1<<3) /* Stream disable */131131+#define USBMODE_BE (1<<2) /* BE/LE endianness select */132132+#define USBMODE_CM_HC (3<<0) /* host controller mode */133133+#define USBMODE_CM_IDLE (0<<0) /* idle state */134134+135135+/* Appendix C, Debug port ... intended for use with special "debug devices"136136+ * that can help if there's no serial console. (nonstandard enumeration.)137137+ */138138+struct ehci_dbg_port {139139+ u32 control;140140+#define DBGP_OWNER (1<<30)141141+#define DBGP_ENABLED (1<<28)142142+#define DBGP_DONE (1<<16)143143+#define DBGP_INUSE (1<<10)144144+#define DBGP_ERRCODE(x) (((x)>>7)&0x07)145145+# define DBGP_ERR_BAD 1146146+# define DBGP_ERR_SIGNAL 2147147+#define DBGP_ERROR (1<<6)148148+#define DBGP_GO (1<<5)149149+#define DBGP_OUT (1<<4)150150+#define DBGP_LEN(x) (((x)>>0)&0x0f)151151+ u32 pids;152152+#define DBGP_PID_GET(x) (((x)>>16)&0xff)153153+#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok))154154+ u32 data03;155155+ u32 data47;156156+ u32 address;157157+#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep))158158+} __attribute__ ((packed));159159+160160+#endif /* __LINUX_USB_EHCI_DEF_H */
-61
include/xen/balloon.h
···11-/******************************************************************************22- * balloon.h33- *44- * Xen balloon driver - enables returning/claiming memory to/from Xen.55- *66- * Copyright (c) 2003, B Dragovic77- * Copyright (c) 2003-2004, M Williamson, K Fraser88- *99- * This program is free software; you can redistribute it and/or1010- * modify it under the terms of the GNU General Public License version 21111- * as published by the Free Software Foundation; or, when distributed1212- * separately from the Linux kernel or incorporated into other1313- * software packages, subject to the following license:1414- *1515- * Permission is hereby granted, free of charge, to any person obtaining a copy1616- * of this source file (the "Software"), to deal in the Software without1717- * restriction, including without limitation the rights to use, copy, modify,1818- * merge, publish, distribute, sublicense, and/or sell copies of the Software,1919- * and to permit persons to whom the Software is furnished to do so, subject to2020- * the following conditions:2121- *2222- * The above copyright notice and this permission notice shall be included in2323- * all copies or substantial portions of the Software.2424- *2525- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR2626- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,2727- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE2828- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER2929- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING3030- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS3131- * IN THE SOFTWARE.3232- */3333-3434-#ifndef __XEN_BALLOON_H__3535-#define __XEN_BALLOON_H__3636-3737-#include <linux/spinlock.h>3838-3939-#if 04040-/*4141- * Inform the balloon driver that it should allow some slop for device-driver4242- * memory activities.4343- */4444-void balloon_update_driver_allowance(long delta);4545-4646-/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */4747-struct page **alloc_empty_pages_and_pagevec(int nr_pages);4848-void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);4949-5050-void balloon_release_driver_page(struct page *page);5151-5252-/*5353- * Prevent the balloon driver from changing the memory reservation during5454- * a driver critical region.5555- */5656-extern spinlock_t balloon_lock;5757-#define balloon_lock(__flags) spin_lock_irqsave(&balloon_lock, __flags)5858-#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)5959-#endif6060-6161-#endif /* __XEN_BALLOON_H__ */
+2
include/xen/events.h
···46464747/* Clear an irq's pending state, in preparation for polling on it */4848void xen_clear_irq_pending(int irq);4949+void xen_set_irq_pending(int irq);5050+bool xen_test_irq_pending(int irq);49515052/* Poll waiting for an irq to become pending. In the usual case, the5153 irq will be disabled so it won't deliver an interrupt. */
+9
lib/Kconfig.debug
···495495496496 If unsure, say N.497497498498+config DEBUG_VIRTUAL499499+ bool "Debug VM translations"500500+ depends on DEBUG_KERNEL && X86501501+ help502502+ Enable some costly sanity checks in virtual to page code. This can503503+ catch mistakes with virt_to_page() and friends.504504+505505+ If unsure, say N.506506+498507config DEBUG_WRITECOUNT499508 bool "Debug filesystem writers count"500509 depends on DEBUG_KERNEL
+1-1
lib/cmdline.c
···126126 * megabyte, or one gigabyte, respectively.127127 */128128129129-unsigned long long memparse(char *ptr, char **retptr)129129+unsigned long long memparse(const char *ptr, char **retptr)130130{131131 char *endptr; /* local pointer to end of parsed string */132132
+7
mm/vmalloc.c
···180180 pmd_t *pmd;181181 pte_t *ptep, pte;182182183183+ /*184184+ * XXX we might need to change this if we add VIRTUAL_BUG_ON for185185+ * architectures that do not vmalloc module space186186+ */187187+ VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) &&188188+ !is_module_address(addr));189189+183190 if (!pgd_none(*pgd)) {184191 pud = pud_offset(pgd, addr);185192 if (!pud_none(*pud)) {