Merge 4.1-rc7 into tty-next

This fixes up a merge issue with the amba-pl011.c driver, and we want
the fixes in this branch as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2015-06-08 10:49:28 -07:00
commit 00fda1682e
501 changed files with 4479 additions and 2389 deletions

View file

@ -162,7 +162,7 @@ Description: Discover CPUs in the same CPU frequency coordination domain
What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1} What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
Date: August 2008 Date: August 2008
KernelVersion: 2.6.27 KernelVersion: 2.6.27
Contact: discuss@x86-64.org Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Disable L3 cache indices Description: Disable L3 cache indices
These files exist in every CPU's cache/index3 directory. Each These files exist in every CPU's cache/index3 directory. Each

View file

@ -17,7 +17,8 @@ Required properties:
- #clock-cells: from common clock binding; shall be set to 1. - #clock-cells: from common clock binding; shall be set to 1.
- clocks: from common clock binding; list of parent clock - clocks: from common clock binding; list of parent clock
handles, shall be xtal reference clock or xtal and clkin for handles, shall be xtal reference clock or xtal and clkin for
si5351c only. si5351c only. Corresponding clock input names are "xtal" and
"clkin" respectively.
- #address-cells: shall be set to 1. - #address-cells: shall be set to 1.
- #size-cells: shall be set to 0. - #size-cells: shall be set to 0.
@ -71,6 +72,7 @@ i2c-master-node {
/* connect xtal input to 25MHz reference */ /* connect xtal input to 25MHz reference */
clocks = <&ref25>; clocks = <&ref25>;
clock-names = "xtal";
/* connect xtal input as source of pll0 and pll1 */ /* connect xtal input as source of pll0 and pll1 */
silabs,pll-source = <0 0>, <1 0>; silabs,pll-source = <0 0>, <1 0>;

View file

@ -3,7 +3,8 @@
Required properties: Required properties:
- compatible: Should be "cdns,[<chip>-]{emac}" - compatible: Should be "cdns,[<chip>-]{emac}"
Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
or the generic form: "cdns,emac". Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
Or the generic form: "cdns,emac".
- reg: Address and length of the register set for the device - reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt - interrupts: Should contain macb interrupt
- phy-mode: see ethernet.txt file in the same directory. - phy-mode: see ethernet.txt file in the same directory.

View file

@ -15,10 +15,8 @@ Optional properties:
- phys: phandle + phy specifier pair - phys: phandle + phy specifier pair
- phy-names: must be "usb" - phy-names: must be "usb"
- dmas: Must contain a list of references to DMA specifiers. - dmas: Must contain a list of references to DMA specifiers.
- dma-names : Must contain a list of DMA names: - dma-names : named "ch%d", where %d is the channel number ranging from zero
- tx0 ... tx<n> to the number of channels (DnFIFOs) minus one.
- rx0 ... rx<n>
- This <n> means DnFIFO in USBHS module.
Example: Example:
usbhs: usb@e6590000 { usbhs: usb@e6590000 {

View file

@ -20,7 +20,7 @@ Supported chips:
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html
* Texas Instruments TMP435 * Texas Instruments TMP435
Prefix: 'tmp435' Prefix: 'tmp435'
Addresses scanned: I2C 0x37, 0x48 - 0x4f Addresses scanned: I2C 0x48 - 0x4f
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html
Authors: Authors:

View file

@ -15,8 +15,7 @@ Contents:
a) Discovering and configuring TCMU uio devices a) Discovering and configuring TCMU uio devices
b) Waiting for events on the device(s) b) Waiting for events on the device(s)
c) Managing the command ring c) Managing the command ring
3) Command filtering and pass_level 3) A final note
4) A final note
TCM Userspace Design TCM Userspace Design
@ -324,7 +323,7 @@ int handle_device_events(int fd, void *map)
/* Process events from cmd ring until we catch up with cmd_head */ /* Process events from cmd ring until we catch up with cmd_head */
while (ent != (void *)mb + mb->cmdr_off + mb->cmd_head) { while (ent != (void *)mb + mb->cmdr_off + mb->cmd_head) {
if (tcmu_hdr_get_op(&ent->hdr) == TCMU_OP_CMD) { if (tcmu_hdr_get_op(ent->hdr.len_op) == TCMU_OP_CMD) {
uint8_t *cdb = (void *)mb + ent->req.cdb_off; uint8_t *cdb = (void *)mb + ent->req.cdb_off;
bool success = true; bool success = true;
@ -339,8 +338,12 @@ int handle_device_events(int fd, void *map)
ent->rsp.scsi_status = SCSI_CHECK_CONDITION; ent->rsp.scsi_status = SCSI_CHECK_CONDITION;
} }
} }
else if (tcmu_hdr_get_op(ent->hdr.len_op) != TCMU_OP_PAD) {
/* Tell the kernel we didn't handle unknown opcodes */
ent->hdr.uflags |= TCMU_UFLAG_UNKNOWN_OP;
}
else { else {
/* Do nothing for PAD entries */ /* Do nothing for PAD entries except update cmd_tail */
} }
/* update cmd_tail */ /* update cmd_tail */
@ -360,28 +363,6 @@ int handle_device_events(int fd, void *map)
} }
Command filtering and pass_level
--------------------------------
TCMU supports a "pass_level" option with valid values of 0 or 1. When
the value is 0 (the default), nearly all SCSI commands received for
the device are passed through to the handler. This allows maximum
flexibility but increases the amount of code required by the handler,
to support all mandatory SCSI commands. If pass_level is set to 1,
then only IO-related commands are presented, and the rest are handled
by LIO's in-kernel command emulation. The commands presented at level
1 include all versions of:
READ
WRITE
WRITE_VERIFY
XDWRITEREAD
WRITE_SAME
COMPARE_AND_WRITE
SYNCHRONIZE_CACHE
UNMAP
A final note A final note
------------ ------------

View file

@ -169,6 +169,10 @@ Shadow pages contain the following information:
Contains the value of cr4.smep && !cr0.wp for which the page is valid Contains the value of cr4.smep && !cr0.wp for which the page is valid
(pages for which this is true are different from other pages; see the (pages for which this is true are different from other pages; see the
treatment of cr0.wp=0 below). treatment of cr0.wp=0 below).
role.smap_andnot_wp:
Contains the value of cr4.smap && !cr0.wp for which the page is valid
(pages for which this is true are different from other pages; see the
treatment of cr0.wp=0 below).
gfn: gfn:
Either the guest page table containing the translations shadowed by this Either the guest page table containing the translations shadowed by this
page, or the base page frame for linear translations. See role.direct. page, or the base page frame for linear translations. See role.direct.
@ -344,10 +348,16 @@ on fault type:
(user write faults generate a #PF) (user write faults generate a #PF)
In the first case there is an additional complication if CR4.SMEP is In the first case there are two additional complications:
enabled: since we've turned the page into a kernel page, the kernel may now - if CR4.SMEP is enabled: since we've turned the page into a kernel page,
execute it. We handle this by also setting spte.nx. If we get a user the kernel may now execute it. We handle this by also setting spte.nx.
fetch or read fault, we'll change spte.u=1 and spte.nx=gpte.nx back. If we get a user fetch or read fault, we'll change spte.u=1 and
spte.nx=gpte.nx back.
- if CR4.SMAP is disabled: since the page has been changed to a kernel
page, it can not be reused when CR4.SMAP is enabled. We set
CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note,
here we do not care the case that CR4.SMAP is enabled since KVM will
directly inject #PF to guest due to failed permission check.
To prevent an spte that was converted into a kernel page with cr0.wp=0 To prevent an spte that was converted into a kernel page with cr0.wp=0
from being written by the kernel after cr0.wp has changed to 1, we make from being written by the kernel after cr0.wp has changed to 1, we make

View file

@ -51,9 +51,9 @@ trivial patch so apply some common sense.
or does something very odd once a month document it. or does something very odd once a month document it.
PLEASE remember that submissions must be made under the terms PLEASE remember that submissions must be made under the terms
of the OSDL certificate of contribution and should include a of the Linux Foundation certificate of contribution and should
Signed-off-by: line. The current version of this "Developer's include a Signed-off-by: line. The current version of this
Certificate of Origin" (DCO) is listed in the file "Developer's Certificate of Origin" (DCO) is listed in the file
Documentation/SubmittingPatches. Documentation/SubmittingPatches.
6. Make sure you have the right to send any changes you make. If you 6. Make sure you have the right to send any changes you make. If you
@ -2427,7 +2427,6 @@ L: linux-security-module@vger.kernel.org
S: Supported S: Supported
F: include/linux/capability.h F: include/linux/capability.h
F: include/uapi/linux/capability.h F: include/uapi/linux/capability.h
F: security/capability.c
F: security/commoncap.c F: security/commoncap.c
F: kernel/capability.c F: kernel/capability.c
@ -3825,10 +3824,11 @@ M: David Woodhouse <dwmw2@infradead.org>
L: linux-embedded@vger.kernel.org L: linux-embedded@vger.kernel.org
S: Maintained S: Maintained
EMULEX LPFC FC SCSI DRIVER EMULEX/AVAGO LPFC FC/FCOE SCSI DRIVER
M: James Smart <james.smart@emulex.com> M: James Smart <james.smart@avagotech.com>
M: Dick Kennedy <dick.kennedy@avagotech.com>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
W: http://sourceforge.net/projects/lpfcxxxx W: http://www.avagotech.com
S: Supported S: Supported
F: drivers/scsi/lpfc/ F: drivers/scsi/lpfc/
@ -4536,7 +4536,7 @@ M: Jean Delvare <jdelvare@suse.de>
M: Guenter Roeck <linux@roeck-us.net> M: Guenter Roeck <linux@roeck-us.net>
L: lm-sensors@lm-sensors.org L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/ W: http://www.lm-sensors.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ T: quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
S: Maintained S: Maintained
F: Documentation/hwmon/ F: Documentation/hwmon/
@ -7575,6 +7575,7 @@ F: drivers/pci/host/pci-exynos.c
PCI DRIVER FOR SYNOPSIS DESIGNWARE PCI DRIVER FOR SYNOPSIS DESIGNWARE
M: Jingoo Han <jingoohan1@gmail.com> M: Jingoo Han <jingoohan1@gmail.com>
M: Pratyush Anand <pratyush.anand@gmail.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Maintained S: Maintained
F: drivers/pci/host/*designware* F: drivers/pci/host/*designware*
@ -7588,8 +7589,9 @@ F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
F: drivers/pci/host/pci-host-generic.c F: drivers/pci/host/pci-host-generic.c
PCIE DRIVER FOR ST SPEAR13XX PCIE DRIVER FOR ST SPEAR13XX
M: Pratyush Anand <pratyush.anand@gmail.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Orphan S: Maintained
F: drivers/pci/host/*spear* F: drivers/pci/host/*spear*
PCMCIA SUBSYSTEM PCMCIA SUBSYSTEM
@ -8829,9 +8831,11 @@ F: drivers/misc/phantom.c
F: include/uapi/linux/phantom.h F: include/uapi/linux/phantom.h
SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
M: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com>
M: Minh Tran <minh.tran@avagotech.com>
M: John Soni Jose <sony.john-n@avagotech.com>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
W: http://www.emulex.com W: http://www.avagotech.com
S: Supported S: Supported
F: drivers/scsi/be2iscsi/ F: drivers/scsi/be2iscsi/
@ -10585,8 +10589,7 @@ F: drivers/virtio/virtio_input.c
F: include/uapi/linux/virtio_input.h F: include/uapi/linux/virtio_input.h
VIA RHINE NETWORK DRIVER VIA RHINE NETWORK DRIVER
M: Roger Luethi <rl@hellgate.ch> S: Orphan
S: Maintained
F: drivers/net/ethernet/via/via-rhine.c F: drivers/net/ethernet/via/via-rhine.c
VIA SD/MMC CARD CONTROLLER DRIVER VIA SD/MMC CARD CONTROLLER DRIVER

View file

@ -1,7 +1,7 @@
VERSION = 4 VERSION = 4
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc4 EXTRAVERSION = -rc7
NAME = Hurr durr I'ma sheep NAME = Hurr durr I'ma sheep
# *DOCUMENTATION* # *DOCUMENTATION*

View file

@ -14,6 +14,9 @@ targets := vmlinux.gz vmlinux \
tools/bootpzh bootloader bootpheader bootpzheader tools/bootpzh bootloader bootpheader bootpzheader
OBJSTRIP := $(obj)/tools/objstrip OBJSTRIP := $(obj)/tools/objstrip
HOSTCFLAGS := -Wall -I$(objtree)/usr/include
BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
# SRM bootable image. Copy to offset 512 of a partition. # SRM bootable image. Copy to offset 512 of a partition.
$(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh $(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh
( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@ ( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@
@ -96,13 +99,14 @@ $(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE
$(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE $(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE
$(call if_changed,objstrip) $(call if_changed,objstrip)
LDFLAGS_bootloader := -static -uvsprintf -T #-N -relax LDFLAGS_bootloader := -static -T # -N -relax
LDFLAGS_bootpheader := -static -uvsprintf -T #-N -relax LDFLAGS_bootloader := -static -T # -N -relax
LDFLAGS_bootpzheader := -static -uvsprintf -T #-N -relax LDFLAGS_bootpheader := -static -T # -N -relax
LDFLAGS_bootpzheader := -static -T # -N -relax
OBJ_bootlx := $(obj)/head.o $(obj)/main.o OBJ_bootlx := $(obj)/head.o $(obj)/stdio.o $(obj)/main.o
OBJ_bootph := $(obj)/head.o $(obj)/bootp.o OBJ_bootph := $(obj)/head.o $(obj)/stdio.o $(obj)/bootp.o
OBJ_bootpzh := $(obj)/head.o $(obj)/bootpz.o $(obj)/misc.o OBJ_bootpzh := $(obj)/head.o $(obj)/stdio.o $(obj)/bootpz.o $(obj)/misc.o
$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE $(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE
$(call if_changed,ld) $(call if_changed,ld)

View file

@ -19,7 +19,6 @@
#include "ksize.h" #include "ksize.h"
extern int vsprintf(char *, const char *, va_list);
extern unsigned long switch_to_osf_pal(unsigned long nr, extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long *vptb); unsigned long *vptb);

306
arch/alpha/boot/stdio.c Normal file
View file

@ -0,0 +1,306 @@
/*
* Copyright (C) Paul Mackerras 1997.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <stdarg.h>
#include <stddef.h>
size_t strnlen(const char * s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
/* nothing */;
return sc - s;
}
# define do_div(n, base) ({ \
unsigned int __base = (base); \
unsigned int __rem; \
__rem = ((unsigned long long)(n)) % __base; \
(n) = ((unsigned long long)(n)) / __base; \
__rem; \
})
static int skip_atoi(const char **s)
{
int i, c;
for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
i = i*10 + c - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
{
char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
int i;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if ((signed long long)num < 0) {
sign = '-';
num = - (signed long long)num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0) {
tmp[i++] = digits[do_div(num, base)];
}
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base==8)
*str++ = '0';
else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
unsigned long long num;
int i, base;
char * str;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
/* 'z' support added 23/7/1999 S.H. */
/* 'z' changed to 'Z' --davidm 1/25/99 */
for (str=buf ; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if ('0' <= *fmt && *fmt <= '9')
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if ('0' <= *fmt && *fmt <= '9')
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'l' && *(fmt + 1) == 'l') {
qualifier = 'q';
fmt += 2;
} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
|| *fmt == 'Z') {
qualifier = *fmt;
++fmt;
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
continue;
case 's':
s = va_arg(args, char *);
if (!s)
s = "<NULL>";
len = strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
continue;
case 'p':
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
str = number(str,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
continue;
case 'n':
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
} else if (qualifier == 'Z') {
size_t * ip = va_arg(args, size_t *);
*ip = (str - buf);
} else {
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
*str++ = '%';
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}
if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
} else if (qualifier == 'q') {
num = va_arg(args, unsigned long long);
if (flags & SIGN)
num = (signed long long) num;
} else if (qualifier == 'Z') {
num = va_arg(args, size_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (signed short) num;
} else {
num = va_arg(args, unsigned int);
if (flags & SIGN)
num = (signed int) num;
}
str = number(str, num, base, field_width, precision, flags);
}
*str = '\0';
return str-buf;
}
int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsprintf(buf,fmt,args);
va_end(args);
return i;
}

View file

@ -27,6 +27,9 @@
#include <linux/param.h> #include <linux/param.h>
#ifdef __ELF__ #ifdef __ELF__
# include <linux/elf.h> # include <linux/elf.h>
# define elfhdr elf64_hdr
# define elf_phdr elf64_phdr
# define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
#endif #endif
/* bootfile size must be multiple of BLOCK_SIZE: */ /* bootfile size must be multiple of BLOCK_SIZE: */

View file

@ -2,6 +2,5 @@
#define _ALPHA_TYPES_H #define _ALPHA_TYPES_H
#include <asm-generic/int-ll64.h> #include <asm-generic/int-ll64.h>
#include <uapi/asm/types.h>
#endif /* _ALPHA_TYPES_H */ #endif /* _ALPHA_TYPES_H */

View file

@ -3,7 +3,7 @@
#include <uapi/asm/unistd.h> #include <uapi/asm/unistd.h>
#define NR_SYSCALLS 511 #define NR_SYSCALLS 514
#define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64 #define __ARCH_WANT_STAT64

View file

@ -472,5 +472,8 @@
#define __NR_sched_setattr 508 #define __NR_sched_setattr 508
#define __NR_sched_getattr 509 #define __NR_sched_getattr 509
#define __NR_renameat2 510 #define __NR_renameat2 510
#define __NR_getrandom 511
#define __NR_memfd_create 512
#define __NR_execveat 513
#endif /* _UAPI_ALPHA_UNISTD_H */ #endif /* _UAPI_ALPHA_UNISTD_H */

View file

@ -6,7 +6,6 @@
* Error handling code supporting Alpha systems * Error handling code supporting Alpha systems
*/ */
#include <linux/init.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/io.h> #include <asm/io.h>

View file

@ -19,7 +19,6 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>

View file

@ -1019,14 +1019,13 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
if (tv) { if (tv) {
if (get_tv32((struct timeval *)&kts, tv)) if (get_tv32((struct timeval *)&kts, tv))
return -EFAULT; return -EFAULT;
kts.tv_nsec *= 1000;
} }
if (tz) { if (tz) {
if (copy_from_user(&ktz, tz, sizeof(*tz))) if (copy_from_user(&ktz, tz, sizeof(*tz)))
return -EFAULT; return -EFAULT;
} }
kts.tv_nsec *= 1000;
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
} }

View file

@ -236,12 +236,11 @@ release_thread(struct task_struct *dead_task)
} }
/* /*
* Copy an alpha thread.. * Copy architecture-specific thread state
*/ */
int int
copy_thread(unsigned long clone_flags, unsigned long usp, copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long arg, unsigned long kthread_arg,
struct task_struct *p) struct task_struct *p)
{ {
extern void ret_from_fork(void); extern void ret_from_fork(void);
@ -262,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
sizeof(struct switch_stack) + sizeof(struct pt_regs)); sizeof(struct switch_stack) + sizeof(struct pt_regs));
childstack->r26 = (unsigned long) ret_from_kernel_thread; childstack->r26 = (unsigned long) ret_from_kernel_thread;
childstack->r9 = usp; /* function */ childstack->r9 = usp; /* function */
childstack->r10 = arg; childstack->r10 = kthread_arg;
childregs->hae = alpha_mv.hae_cache, childregs->hae = alpha_mv.hae_cache,
childti->pcb.usp = 0; childti->pcb.usp = 0;
return 0; return 0;

View file

@ -63,7 +63,6 @@ static struct {
enum ipi_message_type { enum ipi_message_type {
IPI_RESCHEDULE, IPI_RESCHEDULE,
IPI_CALL_FUNC, IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
IPI_CPU_STOP, IPI_CPU_STOP,
}; };
@ -506,7 +505,6 @@ setup_profiling_timer(unsigned int multiplier)
return -EINVAL; return -EINVAL;
} }
static void static void
send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
{ {
@ -552,10 +550,6 @@ handle_ipi(struct pt_regs *regs)
generic_smp_call_function_interrupt(); generic_smp_call_function_interrupt();
break; break;
case IPI_CALL_FUNC_SINGLE:
generic_smp_call_function_single_interrupt();
break;
case IPI_CPU_STOP: case IPI_CPU_STOP:
halt(); halt();
@ -606,7 +600,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
void arch_send_call_function_single_ipi(int cpu) void arch_send_call_function_single_ipi(int cpu)
{ {
send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC);
} }
static void static void

View file

@ -237,8 +237,7 @@ srmcons_init(void)
return -ENODEV; return -ENODEV;
} }
device_initcall(srmcons_init);
module_init(srmcons_init);
/* /*

View file

@ -331,7 +331,7 @@ marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
irq = intline; irq = intline;
msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI); msi_loc = dev->msi_cap;
msg_ctl = 0; msg_ctl = 0;
if (msi_loc) if (msi_loc)
pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl); pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl);

View file

@ -529,6 +529,9 @@ sys_call_table:
.quad sys_sched_setattr .quad sys_sched_setattr
.quad sys_sched_getattr .quad sys_sched_getattr
.quad sys_renameat2 /* 510 */ .quad sys_renameat2 /* 510 */
.quad sys_getrandom
.quad sys_memfd_create
.quad sys_execveat
.size sys_call_table, . - sys_call_table .size sys_call_table, . - sys_call_table
.type sys_call_table, @object .type sys_call_table, @object

View file

@ -14,7 +14,6 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>

View file

@ -8,7 +8,6 @@
*/ */
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>

View file

@ -8,7 +8,6 @@
*/ */
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>

View file

@ -8,7 +8,6 @@
*/ */
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>

View file

@ -9,7 +9,6 @@
*/ */
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>

View file

@ -223,7 +223,7 @@ dtb-$(CONFIG_SOC_IMX25) += \
imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \ imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \
imx25-karo-tx25.dtb \ imx25-karo-tx25.dtb \
imx25-pdk.dtb imx25-pdk.dtb
dtb-$(CONFIG_SOC_IMX31) += \ dtb-$(CONFIG_SOC_IMX27) += \
imx27-apf27.dtb \ imx27-apf27.dtb \
imx27-apf27dev.dtb \ imx27-apf27dev.dtb \
imx27-eukrea-mbimxsd27-baseboard.dtb \ imx27-eukrea-mbimxsd27-baseboard.dtb \

View file

@ -80,7 +80,3 @@ hdmi {
status = "okay"; status = "okay";
}; };
}; };
&rtc {
system-power-controller;
};

View file

@ -654,7 +654,7 @@ &mmc2 {
wlcore: wlcore@2 { wlcore: wlcore@2 {
compatible = "ti,wl1271"; compatible = "ti,wl1271";
reg = <2>; reg = <2>;
interrupt-parent = <&gpio1>; interrupt-parent = <&gpio0>;
interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */ interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */
ref-clock-frequency = <38400000>; ref-clock-frequency = <38400000>;
}; };

View file

@ -736,7 +736,7 @@ panel@0 {
display-timings { display-timings {
timing-0 { timing-0 {
clock-frequency = <0>; clock-frequency = <57153600>;
hactive = <720>; hactive = <720>;
vactive = <1280>; vactive = <1280>;
hfront-porch = <5>; hfront-porch = <5>;

View file

@ -533,7 +533,7 @@ iim: iim@10028000 {
fec: ethernet@1002b000 { fec: ethernet@1002b000 {
compatible = "fsl,imx27-fec"; compatible = "fsl,imx27-fec";
reg = <0x1002b000 0x4000>; reg = <0x1002b000 0x1000>;
interrupts = <50>; interrupts = <50>;
clocks = <&clks IMX27_CLK_FEC_IPG_GATE>, clocks = <&clks IMX27_CLK_FEC_IPG_GATE>,
<&clks IMX27_CLK_FEC_AHB_GATE>; <&clks IMX27_CLK_FEC_AHB_GATE>;

View file

@ -110,6 +110,8 @@ &gpmc {
nand@0,0 { nand@0,0 {
reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
nand-bus-width = <16>; nand-bus-width = <16>;
gpmc,device-width = <2>;
ti,nand-ecc-opt = "sw";
gpmc,sync-clk-ps = <0>; gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>; gpmc,cs-on-ns = <0>;

View file

@ -193,7 +193,7 @@ spi1: spi@e0007000 {
}; };
gem0: ethernet@e000b000 { gem0: ethernet@e000b000 {
compatible = "cdns,gem"; compatible = "cdns,zynq-gem";
reg = <0xe000b000 0x1000>; reg = <0xe000b000 0x1000>;
status = "disabled"; status = "disabled";
interrupts = <0 22 4>; interrupts = <0 22 4>;
@ -204,7 +204,7 @@ gem0: ethernet@e000b000 {
}; };
gem1: ethernet@e000c000 { gem1: ethernet@e000c000 {
compatible = "cdns,gem"; compatible = "cdns,zynq-gem";
reg = <0xe000c000 0x1000>; reg = <0xe000c000 0x1000>;
status = "disabled"; status = "disabled";
interrupts = <0 45 4>; interrupts = <0 45 4>;

View file

@ -429,7 +429,7 @@ CONFIG_USB_EHCI_EXYNOS=y
CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_EHCI_TEGRA=y
CONFIG_USB_EHCI_HCD_STI=y CONFIG_USB_EHCI_HCD_STI=y
CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_ISP1760_HCD=y CONFIG_USB_ISP1760=y
CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_STI=y CONFIG_USB_OHCI_HCD_STI=y
CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD_PLATFORM=y

View file

@ -33,7 +33,9 @@ ret_fast_syscall:
UNWIND(.fnstart ) UNWIND(.fnstart )
UNWIND(.cantunwind ) UNWIND(.cantunwind )
disable_irq @ disable interrupts disable_irq @ disable interrupts
ldr r1, [tsk, #TI_FLAGS] ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
tst r1, #_TIF_SYSCALL_WORK
bne __sys_trace_return
tst r1, #_TIF_WORK_MASK tst r1, #_TIF_WORK_MASK
bne fast_work_pending bne fast_work_pending
asm_trace_hardirqs_on asm_trace_hardirqs_on

View file

@ -304,16 +304,17 @@ static int probe_current_pmu(struct arm_pmu *pmu)
static int of_pmu_irq_cfg(struct platform_device *pdev) static int of_pmu_irq_cfg(struct platform_device *pdev)
{ {
int i, irq; int i, irq;
int *irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); int *irqs;
if (!irqs)
return -ENOMEM;
/* Don't bother with PPIs; they're already affine */ /* Don't bother with PPIs; they're already affine */
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq >= 0 && irq_is_percpu(irq)) if (irq >= 0 && irq_is_percpu(irq))
return 0; return 0;
irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
if (!irqs)
return -ENOMEM;
for (i = 0; i < pdev->num_resources; ++i) { for (i = 0; i < pdev->num_resources; ++i) {
struct device_node *dn; struct device_node *dn;
int cpu; int cpu;

View file

@ -280,9 +280,15 @@ void __init imx_gpc_check_dt(void)
struct device_node *np; struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
if (WARN_ON(!np || if (WARN_ON(!np))
!of_find_property(np, "interrupt-controller", NULL))) return;
pr_warn("Outdated DT detected, system is about to crash!!!\n");
if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
/* map GPC, so that at least CPUidle and WARs keep working */
gpc_base = of_iomap(np, 0);
}
} }
#ifdef CONFIG_PM_GENERIC_DOMAINS #ifdef CONFIG_PM_GENERIC_DOMAINS
@ -443,6 +449,10 @@ static int imx_gpc_probe(struct platform_device *pdev)
struct regulator *pu_reg; struct regulator *pu_reg;
int ret; int ret;
/* bail out if DT too old and doesn't provide the necessary info */
if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells"))
return 0;
pu_reg = devm_regulator_get_optional(&pdev->dev, "pu"); pu_reg = devm_regulator_get_optional(&pdev->dev, "pu");
if (PTR_ERR(pu_reg) == -ENODEV) if (PTR_ERR(pu_reg) == -ENODEV)
pu_reg = NULL; pu_reg = NULL;

View file

@ -107,7 +107,7 @@ static int cplds_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
struct cplds *fpga; struct cplds *fpga;
int ret; int ret;
unsigned int base_irq = 0; int base_irq;
unsigned long irqflags = 0; unsigned long irqflags = 0;
fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL); fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL);

View file

@ -1112,22 +1112,22 @@ void __init sanity_check_meminfo(void)
} }
/* /*
* Find the first non-section-aligned page, and point * Find the first non-pmd-aligned page, and point
* memblock_limit at it. This relies on rounding the * memblock_limit at it. This relies on rounding the
* limit down to be section-aligned, which happens at * limit down to be pmd-aligned, which happens at the
* the end of this function. * end of this function.
* *
* With this algorithm, the start or end of almost any * With this algorithm, the start or end of almost any
* bank can be non-section-aligned. The only exception * bank can be non-pmd-aligned. The only exception is
* is that the start of the bank 0 must be section- * that the start of the bank 0 must be section-
* aligned, since otherwise memory would need to be * aligned, since otherwise memory would need to be
* allocated when mapping the start of bank 0, which * allocated when mapping the start of bank 0, which
* occurs before any free memory is mapped. * occurs before any free memory is mapped.
*/ */
if (!memblock_limit) { if (!memblock_limit) {
if (!IS_ALIGNED(block_start, SECTION_SIZE)) if (!IS_ALIGNED(block_start, PMD_SIZE))
memblock_limit = block_start; memblock_limit = block_start;
else if (!IS_ALIGNED(block_end, SECTION_SIZE)) else if (!IS_ALIGNED(block_end, PMD_SIZE))
memblock_limit = arm_lowmem_limit; memblock_limit = arm_lowmem_limit;
} }
@ -1137,12 +1137,12 @@ void __init sanity_check_meminfo(void)
high_memory = __va(arm_lowmem_limit - 1) + 1; high_memory = __va(arm_lowmem_limit - 1) + 1;
/* /*
* Round the memblock limit down to a section size. This * Round the memblock limit down to a pmd size. This
* helps to ensure that we will allocate memory from the * helps to ensure that we will allocate memory from the
* last full section, which should be mapped. * last full pmd, which should be mapped.
*/ */
if (memblock_limit) if (memblock_limit)
memblock_limit = round_down(memblock_limit, SECTION_SIZE); memblock_limit = round_down(memblock_limit, PMD_SIZE);
if (!memblock_limit) if (!memblock_limit)
memblock_limit = arm_lowmem_limit; memblock_limit = arm_lowmem_limit;

View file

@ -272,6 +272,7 @@ void xen_arch_pre_suspend(void) { }
void xen_arch_post_suspend(int suspend_cancelled) { } void xen_arch_post_suspend(int suspend_cancelled) { }
void xen_timer_resume(void) { } void xen_timer_resume(void) { }
void xen_arch_resume(void) { } void xen_arch_resume(void) { }
void xen_arch_suspend(void) { }
/* In the hypervisor.S file. */ /* In the hypervisor.S file. */

View file

@ -127,7 +127,7 @@ int smp_num_siblings = 1;
volatile int ia64_cpu_to_sapicid[NR_CPUS]; volatile int ia64_cpu_to_sapicid[NR_CPUS];
EXPORT_SYMBOL(ia64_cpu_to_sapicid); EXPORT_SYMBOL(ia64_cpu_to_sapicid);
static volatile cpumask_t cpu_callin_map; static cpumask_t cpu_callin_map;
struct smp_boot_data smp_boot_data __initdata; struct smp_boot_data smp_boot_data __initdata;
@ -477,6 +477,7 @@ do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
for (timeout = 0; timeout < 100000; timeout++) { for (timeout = 0; timeout < 100000; timeout++) {
if (cpumask_test_cpu(cpu, &cpu_callin_map)) if (cpumask_test_cpu(cpu, &cpu_callin_map))
break; /* It has booted */ break; /* It has booted */
barrier(); /* Make sure we re-read cpu_callin_map */
udelay(100); udelay(100);
} }
Dprintk("\n"); Dprintk("\n");

View file

@ -478,9 +478,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
{ {
struct pci_controller *controller = bridge->bus->sysdata; /*
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
ACPI_COMPANION_SET(&bridge->dev, controller->companion); * here, pci_create_root_bus() has been called by someone else and
* sysdata is likely to be different from what we expect. Let it go in
* that case.
*/
if (!bridge->dev.parent) {
struct pci_controller *controller = bridge->bus->sysdata;
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
}
return 0; return 0;
} }

View file

@ -1,6 +1,7 @@
/* /*
* Atheros AR71XX/AR724X/AR913X specific prom routines * Atheros AR71XX/AR724X/AR913X specific prom routines
* *
* Copyright (C) 2015 Laurent Fasnacht <l@libres.ch>
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
* *
@ -25,12 +26,14 @@ void __init prom_init(void)
{ {
fw_init_cmdline(); fw_init_cmdline();
#ifdef CONFIG_BLK_DEV_INITRD
/* Read the initrd address from the firmware environment */ /* Read the initrd address from the firmware environment */
initrd_start = fw_getenvl("initrd_start"); initrd_start = fw_getenvl("initrd_start");
if (initrd_start) { if (initrd_start) {
initrd_start = KSEG0ADDR(initrd_start); initrd_start = KSEG0ADDR(initrd_start);
initrd_end = initrd_start + fw_getenvl("initrd_size"); initrd_end = initrd_start + fw_getenvl("initrd_size");
} }
#endif
} }
void __init prom_free_prom_memory(void) void __init prom_free_prom_memory(void)

View file

@ -225,7 +225,7 @@ void __init plat_time_init(void)
ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); ddr_clk_rate = ath79_get_sys_clk_rate("ddr");
ref_clk_rate = ath79_get_sys_clk_rate("ref"); ref_clk_rate = ath79_get_sys_clk_rate("ref");
pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz", pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n",
cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000, cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000, ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000,
ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000, ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000,

View file

@ -194,7 +194,7 @@ CONFIG_USB_WUSB_CBAF=m
CONFIG_USB_C67X00_HCD=m CONFIG_USB_C67X00_HCD=m
CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_ISP1760_HCD=m CONFIG_USB_ISP1760=m
CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=m CONFIG_USB_UHCI_HCD=m
CONFIG_USB_R8A66597_HCD=m CONFIG_USB_R8A66597_HCD=m

View file

@ -74,13 +74,12 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
{ {
unsigned long sr, mask, fcsr, fcsr0, fcsr1; unsigned long sr, mask, fcsr, fcsr0, fcsr1;
fcsr = c->fpu_csr31;
mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM;
sr = read_c0_status(); sr = read_c0_status();
__enable_fpu(FPU_AS_IS); __enable_fpu(FPU_AS_IS);
fcsr = read_32bit_cp1_register(CP1_STATUS);
fcsr0 = fcsr & mask; fcsr0 = fcsr & mask;
write_32bit_cp1_register(CP1_STATUS, fcsr0); write_32bit_cp1_register(CP1_STATUS, fcsr0);
fcsr0 = read_32bit_cp1_register(CP1_STATUS); fcsr0 = read_32bit_cp1_register(CP1_STATUS);

View file

@ -29,7 +29,7 @@
int kgdb_early_setup; int kgdb_early_setup;
#endif #endif
static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; static DECLARE_BITMAP(irq_map, NR_IRQS);
int allocate_irqno(void) int allocate_irqno(void)
{ {
@ -109,7 +109,7 @@ void __init init_IRQ(void)
#endif #endif
} }
#ifdef DEBUG_STACKOVERFLOW #ifdef CONFIG_DEBUG_STACKOVERFLOW
static inline void check_stack_overflow(void) static inline void check_stack_overflow(void)
{ {
unsigned long sp; unsigned long sp;

View file

@ -444,7 +444,7 @@ struct plat_smp_ops bmips5000_smp_ops = {
static void bmips_wr_vec(unsigned long dst, char *start, char *end) static void bmips_wr_vec(unsigned long dst, char *start, char *end)
{ {
memcpy((void *)dst, start, end - start); memcpy((void *)dst, start, end - start);
dma_cache_wback((unsigned long)start, end - start); dma_cache_wback(dst, end - start);
local_flush_icache_range(dst, dst + (end - start)); local_flush_icache_range(dst, dst + (end - start));
instruction_hazard(); instruction_hazard();
} }

View file

@ -2409,7 +2409,7 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
if (vcpu->mmio_needed == 2) if (vcpu->mmio_needed == 2)
*gpr = *(int16_t *) run->mmio.data; *gpr = *(int16_t *) run->mmio.data;
else else
*gpr = *(int16_t *) run->mmio.data; *gpr = *(uint16_t *)run->mmio.data;
break; break;
case 1: case 1:

View file

@ -34,7 +34,12 @@ LEAF(__strnlen_\func\()_asm)
FEXPORT(__strnlen_\func\()_nocheck_asm) FEXPORT(__strnlen_\func\()_nocheck_asm)
move v0, a0 move v0, a0
PTR_ADDU a1, a0 # stop pointer PTR_ADDU a1, a0 # stop pointer
1: beq v0, a1, 1f # limit reached? 1:
#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
.set noat
li AT, 1
#endif
beq v0, a1, 1f # limit reached?
.ifeqs "\func", "kernel" .ifeqs "\func", "kernel"
EX(lb, t0, (v0), .Lfault\@) EX(lb, t0, (v0), .Lfault\@)
.else .else
@ -42,7 +47,13 @@ FEXPORT(__strnlen_\func\()_nocheck_asm)
.endif .endif
.set noreorder .set noreorder
bnez t0, 1b bnez t0, 1b
1: PTR_ADDIU v0, 1 1:
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
PTR_ADDIU v0, 1
#else
PTR_ADDU v0, AT
.set at
#endif
.set reorder .set reorder
PTR_SUBU v0, a0 PTR_SUBU v0, a0
jr ra jr ra

View file

@ -272,7 +272,7 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
if (action & SMP_ASK_C0COUNT) { if (action & SMP_ASK_C0COUNT) {
BUG_ON(cpu != 0); BUG_ON(cpu != 0);
c0count = read_c0_count(); c0count = read_c0_count();
for (i = 1; i < loongson_sysconf.nr_cpus; i++) for (i = 1; i < num_possible_cpus(); i++)
per_cpu(core0_c0count, i) = c0count; per_cpu(core0_c0count, i) = c0count;
} }
} }

View file

@ -1372,7 +1372,7 @@ static int probe_scache(void)
scache_size = addr; scache_size = addr;
c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22);
c->scache.ways = 1; c->scache.ways = 1;
c->dcache.waybit = 0; /* does not matter */ c->scache.waybit = 0; /* does not matter */
return 1; return 1;
} }

View file

@ -681,11 +681,7 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
sp_off += config_enabled(CONFIG_64BIT) ? sp_off += config_enabled(CONFIG_64BIT) ?
(ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE; (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE;
/* return sp_off;
* Subtract the bytes for the last registers since we only care about
* the location on the stack pointer.
*/
return sp_off - RSIZE;
} }
static void build_prologue(struct jit_ctx *ctx) static void build_prologue(struct jit_ctx *ctx)

View file

@ -41,7 +41,7 @@ static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
type & ILL_ACC_LEN_M); type & ILL_ACC_LEN_M);
rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View file

@ -73,7 +73,7 @@ void save_mce_event(struct pt_regs *regs, long handled,
uint64_t nip, uint64_t addr) uint64_t nip, uint64_t addr)
{ {
uint64_t srr1; uint64_t srr1;
int index = __this_cpu_inc_return(mce_nest_count); int index = __this_cpu_inc_return(mce_nest_count) - 1;
struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]); struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]);
/* /*
@ -184,7 +184,7 @@ void machine_check_queue_event(void)
if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
return; return;
index = __this_cpu_inc_return(mce_queue_count); index = __this_cpu_inc_return(mce_queue_count) - 1;
/* If queue is full, just return for now. */ /* If queue is full, just return for now. */
if (index >= MAX_MC_EVT) { if (index >= MAX_MC_EVT) {
__this_cpu_dec(mce_queue_count); __this_cpu_dec(mce_queue_count);

View file

@ -213,6 +213,7 @@ SECTIONS
*(.opd) *(.opd)
} }
. = ALIGN(256);
.got : AT(ADDR(.got) - LOAD_OFFSET) { .got : AT(ADDR(.got) - LOAD_OFFSET) {
__toc_start = .; __toc_start = .;
#ifndef CONFIG_RELOCATABLE #ifndef CONFIG_RELOCATABLE

View file

@ -1952,7 +1952,7 @@ static void post_guest_process(struct kvmppc_vcore *vc)
*/ */
static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
{ {
struct kvm_vcpu *vcpu; struct kvm_vcpu *vcpu, *vnext;
int i; int i;
int srcu_idx; int srcu_idx;
@ -1982,7 +1982,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
*/ */
if ((threads_per_core > 1) && if ((threads_per_core > 1) &&
((vc->num_threads > threads_per_subcore) || !on_primary_thread())) { ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) {
list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,
arch.run_list) {
vcpu->arch.ret = -EBUSY; vcpu->arch.ret = -EBUSY;
kvmppc_remove_runnable(vc, vcpu); kvmppc_remove_runnable(vc, vcpu);
wake_up(&vcpu->arch.cpu_run); wake_up(&vcpu->arch.cpu_run);

View file

@ -689,27 +689,34 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
struct page * struct page *
follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
{ {
pte_t *ptep; pte_t *ptep, pte;
struct page *page;
unsigned shift; unsigned shift;
unsigned long mask, flags; unsigned long mask, flags;
struct page *page = ERR_PTR(-EINVAL);
local_irq_save(flags);
ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
if (!ptep)
goto no_page;
pte = READ_ONCE(*ptep);
/* /*
* Verify it is a huge page else bail.
* Transparent hugepages are handled by generic code. We can skip them * Transparent hugepages are handled by generic code. We can skip them
* here. * here.
*/ */
local_irq_save(flags); if (!shift || pmd_trans_huge(__pmd(pte_val(pte))))
ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift); goto no_page;
/* Verify it is a huge page else bail. */ if (!pte_present(pte)) {
if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) { page = NULL;
local_irq_restore(flags); goto no_page;
return ERR_PTR(-EINVAL);
} }
mask = (1UL << shift) - 1; mask = (1UL << shift) - 1;
page = pte_page(*ptep); page = pte_page(pte);
if (page) if (page)
page += (address & mask) / PAGE_SIZE; page += (address & mask) / PAGE_SIZE;
no_page:
local_irq_restore(flags); local_irq_restore(flags);
return page; return page;
} }

View file

@ -839,6 +839,17 @@ pmd_t pmdp_get_and_clear(struct mm_struct *mm,
* hash fault look at them. * hash fault look at them.
*/ */
memset(pgtable, 0, PTE_FRAG_SIZE); memset(pgtable, 0, PTE_FRAG_SIZE);
/*
* Serialize against find_linux_pte_or_hugepte which does lock-less
* lookup in page tables with local interrupts disabled. For huge pages
* it casts pmd_t to pte_t. Since format of pte_t is different from
* pmd_t we want to prevent transit from pmd pointing to page table
* to pmd pointing to huge page (and back) while interrupts are disabled.
* We clear pmd to possibly replace it with page table pointer in
* different code paths. So make sure we wait for the parallel
* find_linux_pte_or_hugepage to finish.
*/
kick_all_cpus_sync();
return old_pmd; return old_pmd;
} }

View file

@ -16,11 +16,12 @@
#define GHASH_DIGEST_SIZE 16 #define GHASH_DIGEST_SIZE 16
struct ghash_ctx { struct ghash_ctx {
u8 icv[16]; u8 key[GHASH_BLOCK_SIZE];
u8 key[16];
}; };
struct ghash_desc_ctx { struct ghash_desc_ctx {
u8 icv[GHASH_BLOCK_SIZE];
u8 key[GHASH_BLOCK_SIZE];
u8 buffer[GHASH_BLOCK_SIZE]; u8 buffer[GHASH_BLOCK_SIZE];
u32 bytes; u32 bytes;
}; };
@ -28,8 +29,10 @@ struct ghash_desc_ctx {
static int ghash_init(struct shash_desc *desc) static int ghash_init(struct shash_desc *desc)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
memset(dctx, 0, sizeof(*dctx)); memset(dctx, 0, sizeof(*dctx));
memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE);
return 0; return 0;
} }
@ -45,7 +48,6 @@ static int ghash_setkey(struct crypto_shash *tfm,
} }
memcpy(ctx->key, key, GHASH_BLOCK_SIZE); memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
return 0; return 0;
} }
@ -54,7 +56,6 @@ static int ghash_update(struct shash_desc *desc,
const u8 *src, unsigned int srclen) const u8 *src, unsigned int srclen)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
unsigned int n; unsigned int n;
u8 *buf = dctx->buffer; u8 *buf = dctx->buffer;
int ret; int ret;
@ -70,7 +71,7 @@ static int ghash_update(struct shash_desc *desc,
src += n; src += n;
if (!dctx->bytes) { if (!dctx->bytes) {
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf,
GHASH_BLOCK_SIZE); GHASH_BLOCK_SIZE);
if (ret != GHASH_BLOCK_SIZE) if (ret != GHASH_BLOCK_SIZE)
return -EIO; return -EIO;
@ -79,7 +80,7 @@ static int ghash_update(struct shash_desc *desc,
n = srclen & ~(GHASH_BLOCK_SIZE - 1); n = srclen & ~(GHASH_BLOCK_SIZE - 1);
if (n) { if (n) {
ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); ret = crypt_s390_kimd(KIMD_GHASH, dctx, src, n);
if (ret != n) if (ret != n)
return -EIO; return -EIO;
src += n; src += n;
@ -94,7 +95,7 @@ static int ghash_update(struct shash_desc *desc,
return 0; return 0;
} }
static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) static int ghash_flush(struct ghash_desc_ctx *dctx)
{ {
u8 *buf = dctx->buffer; u8 *buf = dctx->buffer;
int ret; int ret;
@ -104,24 +105,24 @@ static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
memset(pos, 0, dctx->bytes); memset(pos, 0, dctx->bytes);
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); ret = crypt_s390_kimd(KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
if (ret != GHASH_BLOCK_SIZE) if (ret != GHASH_BLOCK_SIZE)
return -EIO; return -EIO;
dctx->bytes = 0;
} }
dctx->bytes = 0;
return 0; return 0;
} }
static int ghash_final(struct shash_desc *desc, u8 *dst) static int ghash_final(struct shash_desc *desc, u8 *dst)
{ {
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
int ret; int ret;
ret = ghash_flush(ctx, dctx); ret = ghash_flush(dctx);
if (!ret) if (!ret)
memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE);
return ret; return ret;
} }

View file

@ -125,7 +125,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes)
/* fill page with urandom bytes */ /* fill page with urandom bytes */
get_random_bytes(pg, PAGE_SIZE); get_random_bytes(pg, PAGE_SIZE);
/* exor page with stckf values */ /* exor page with stckf values */
for (n = 0; n < sizeof(PAGE_SIZE/sizeof(u64)); n++) { for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) {
u64 *p = ((u64 *)pg) + n; u64 *p = ((u64 *)pg) + n;
*p ^= get_tod_clock_fast(); *p ^= get_tod_clock_fast();
} }

View file

@ -494,7 +494,7 @@ static inline int pmd_large(pmd_t pmd)
return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0;
} }
static inline int pmd_pfn(pmd_t pmd) static inline unsigned long pmd_pfn(pmd_t pmd)
{ {
unsigned long origin_mask; unsigned long origin_mask;

View file

@ -443,8 +443,11 @@ static void bpf_jit_epilogue(struct bpf_jit *jit)
/* /*
* Compile one eBPF instruction into s390x code * Compile one eBPF instruction into s390x code
*
* NOTE: Use noinline because for gcov (-fprofile-arcs) gcc allocates a lot of
* stack space for the large switch statement.
*/ */
static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
{ {
struct bpf_insn *insn = &fp->insnsi[i]; struct bpf_insn *insn = &fp->insnsi[i];
int jmp_off, last, insn_count = 1; int jmp_off, last, insn_count = 1;
@ -588,8 +591,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
EMIT4(0xb9160000, dst_reg, rc_reg); EMIT4(0xb9160000, dst_reg, rc_reg);
break; break;
} }
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / (u32) src */ case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % (u32) src */ case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % src */
{ {
int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
@ -602,10 +605,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
EMIT4_IMM(0xa7090000, REG_W0, 0); EMIT4_IMM(0xa7090000, REG_W0, 0);
/* lgr %w1,%dst */ /* lgr %w1,%dst */
EMIT4(0xb9040000, REG_W1, dst_reg); EMIT4(0xb9040000, REG_W1, dst_reg);
/* llgfr %dst,%src (u32 cast) */
EMIT4(0xb9160000, dst_reg, src_reg);
/* dlgr %w0,%dst */ /* dlgr %w0,%dst */
EMIT4(0xb9870000, REG_W0, dst_reg); EMIT4(0xb9870000, REG_W0, src_reg);
/* lgr %dst,%rc */ /* lgr %dst,%rc */
EMIT4(0xb9040000, dst_reg, rc_reg); EMIT4(0xb9040000, dst_reg, rc_reg);
break; break;
@ -632,8 +633,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
EMIT4(0xb9160000, dst_reg, rc_reg); EMIT4(0xb9160000, dst_reg, rc_reg);
break; break;
} }
case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / (u32) imm */ case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */
case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % (u32) imm */ case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % imm */
{ {
int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
@ -649,7 +650,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
EMIT4(0xb9040000, REG_W1, dst_reg); EMIT4(0xb9040000, REG_W1, dst_reg);
/* dlg %w0,<d(imm)>(%l) */ /* dlg %w0,<d(imm)>(%l) */
EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L, EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L,
EMIT_CONST_U64((u32) imm)); EMIT_CONST_U64(imm));
/* lgr %dst,%rc */ /* lgr %dst,%rc */
EMIT4(0xb9040000, dst_reg, rc_reg); EMIT4(0xb9040000, dst_reg, rc_reg);
break; break;

View file

@ -24,7 +24,8 @@ typedef struct {
unsigned int icache_line_size; unsigned int icache_line_size;
unsigned int ecache_size; unsigned int ecache_size;
unsigned int ecache_line_size; unsigned int ecache_line_size;
int core_id; unsigned short sock_id;
unsigned short core_id;
int proc_id; int proc_id;
} cpuinfo_sparc; } cpuinfo_sparc;

View file

@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
" sllx %1, 32, %1\n" " sllx %1, 32, %1\n"
" or %0, %1, %0\n" " or %0, %1, %0\n"
" .previous\n" " .previous\n"
" .section .sun_m7_2insn_patch, \"ax\"\n"
" .word 661b\n"
" sethi %%uhi(%4), %1\n"
" sethi %%hi(%4), %0\n"
" .word 662b\n"
" or %1, %%ulo(%4), %1\n"
" or %0, %%lo(%4), %0\n"
" .word 663b\n"
" sllx %1, 32, %1\n"
" or %0, %1, %0\n"
" .previous\n"
: "=r" (mask), "=r" (tmp) : "=r" (mask), "=r" (tmp)
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_E_4V |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
" andn %0, %4, %0\n" " andn %0, %4, %0\n"
" or %0, %5, %0\n" " or %0, %5, %0\n"
" .previous\n" " .previous\n"
" .section .sun_m7_2insn_patch, \"ax\"\n"
" .word 661b\n"
" andn %0, %6, %0\n"
" or %0, %5, %0\n"
" .previous\n"
: "=r" (val) : "=r" (val)
: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V)); "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V),
"i" (_PAGE_CP_4V));
return __pgprot(val); return __pgprot(val);
} }

View file

@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_id) #define topology_core_id(cpu) (cpu_data(cpu).core_id)
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern cpumask_t cpu_core_map[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS];
extern cpumask_t cpu_core_sib_map[NR_CPUS];
static inline const struct cpumask *cpu_coregroup_mask(int cpu) static inline const struct cpumask *cpu_coregroup_mask(int cpu)
{ {
return &cpu_core_map[cpu]; return &cpu_core_map[cpu];

View file

@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
}; };
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
__sun4v_2insn_patch_end; __sun4v_2insn_patch_end;
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
__sun_m7_2insn_patch_end;
#endif /* !(__ASSEMBLY__) */ #endif /* !(__ASSEMBLY__) */

View file

@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *); struct sun4v_1insn_patch_entry *);
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
struct sun4v_2insn_patch_entry *); struct sun4v_2insn_patch_entry *);
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *,
struct sun4v_2insn_patch_entry *);
extern unsigned int dcache_parity_tl1_occurred; extern unsigned int dcache_parity_tl1_occurred;
extern unsigned int icache_parity_tl1_occurred; extern unsigned int icache_parity_tl1_occurred;

View file

@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev)
err = -ENOMEM; err = -ENOMEM;
goto err1; goto err1;
} }
memset(grpci2priv, 0, sizeof(*grpci2priv));
priv->regs = regs; priv->regs = regs;
priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */ priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT; priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;

View file

@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
} }
} }
static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) static void find_back_node_value(struct mdesc_handle *hp, u64 node,
char *srch_val,
void (*func)(struct mdesc_handle *, u64, int),
u64 val, int depth)
{ {
u64 a; u64 arc;
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { /* Since we have an estimate of recursion depth, do a sanity check. */
u64 t = mdesc_arc_target(hp, a); if (depth == 0)
const char *name; return;
const u64 *id;
name = mdesc_node_name(hp, t); mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
if (!strcmp(name, "cpu")) { u64 n = mdesc_arc_target(hp, arc);
id = mdesc_get_property(hp, t, "id", NULL); const char *name = mdesc_node_name(hp, n);
if (*id < NR_CPUS)
cpu_data(*id).core_id = core_id;
} else {
u64 j;
mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { if (!strcmp(srch_val, name))
u64 n = mdesc_arc_target(hp, j); (*func)(hp, n, val);
const char *n_name;
n_name = mdesc_node_name(hp, n); find_back_node_value(hp, n, srch_val, func, val, depth-1);
if (strcmp(n_name, "cpu"))
continue;
id = mdesc_get_property(hp, n, "id", NULL);
if (*id < NR_CPUS)
cpu_data(*id).core_id = core_id;
}
}
} }
} }
static void __mark_core_id(struct mdesc_handle *hp, u64 node,
int core_id)
{
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
if (*id < num_possible_cpus())
cpu_data(*id).core_id = core_id;
}
static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
int sock_id)
{
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
if (*id < num_possible_cpus())
cpu_data(*id).sock_id = sock_id;
}
static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
int core_id)
{
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
}
static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
int sock_id)
{
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
}
static void set_core_ids(struct mdesc_handle *hp) static void set_core_ids(struct mdesc_handle *hp)
{ {
int idx; int idx;
u64 mp; u64 mp;
idx = 1; idx = 1;
/* Identify unique cores by looking for cpus backpointed to by
* level 1 instruction caches.
*/
mdesc_for_each_node_by_name(hp, mp, "cache") { mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *level; const u64 *level;
const char *type; const char *type;
@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
continue; continue;
mark_core_ids(hp, mp, idx); mark_core_ids(hp, mp, idx);
idx++; idx++;
} }
} }
static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
{
u64 mp;
int idx = 1;
int fnd = 0;
/* Identify unique sockets by looking for cpus backpointed to by
* shared level n caches.
*/
mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *cur_lvl;
cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
if (*cur_lvl != level)
continue;
mark_sock_ids(hp, mp, idx);
idx++;
fnd = 1;
}
return fnd;
}
static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
{
int idx = 1;
mdesc_for_each_node_by_name(hp, mp, "socket") {
u64 a;
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
u64 t = mdesc_arc_target(hp, a);
const char *name;
const u64 *id;
name = mdesc_node_name(hp, t);
if (strcmp(name, "cpu"))
continue;
id = mdesc_get_property(hp, t, "id", NULL);
if (*id < num_possible_cpus())
cpu_data(*id).sock_id = idx;
}
idx++;
}
}
static void set_sock_ids(struct mdesc_handle *hp)
{
u64 mp;
/* If machine description exposes sockets data use it.
* Otherwise fallback to use shared L3 or L2 caches.
*/
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
if (mp != MDESC_NODE_NULL)
return set_sock_ids_by_socket(hp, mp);
if (!set_sock_ids_by_cache(hp, 3))
set_sock_ids_by_cache(hp, 2);
}
static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
{ {
u64 a; u64 a;
@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
continue; continue;
mark_proc_ids(hp, mp, idx); mark_proc_ids(hp, mp, idx);
idx++; idx++;
} }
} }
@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)
set_core_ids(hp); set_core_ids(hp);
set_proc_ids(hp); set_proc_ids(hp);
set_sock_ids(hp);
mdesc_release(hp); mdesc_release(hp);

View file

@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init); subsys_initcall(pcibios_init);
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */
static void pcie_bus_slot_names(struct pci_bus *pbus)
{
struct pci_dev *pdev;
struct pci_bus *bus;
list_for_each_entry(pdev, &pbus->devices, bus_list) {
char name[SLOT_NAME_SIZE];
struct pci_slot *pci_slot;
const u32 *slot_num;
int len;
slot_num = of_get_property(pdev->dev.of_node,
"physical-slot#", &len);
if (slot_num == NULL || len != 4)
continue;
snprintf(name, sizeof(name), "%u", slot_num[0]);
pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);
if (IS_ERR(pci_slot))
pr_err("PCI: pci_create_slot returned %ld.\n",
PTR_ERR(pci_slot));
}
list_for_each_entry(bus, &pbus->children, node)
pcie_bus_slot_names(bus);
}
static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
{ {
const struct pci_slot_names { const struct pci_slot_names {
@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)
while ((pbus = pci_find_next_bus(pbus)) != NULL) { while ((pbus = pci_find_next_bus(pbus)) != NULL) {
struct device_node *node; struct device_node *node;
struct pci_dev *pdev;
if (pbus->self) { pdev = list_first_entry(&pbus->devices, struct pci_dev,
/* PCI->PCI bridge */ bus_list);
node = pbus->self->dev.of_node;
if (pdev && pci_is_pcie(pdev)) {
pcie_bus_slot_names(pbus);
} else { } else {
struct pci_pbm_info *pbm = pbus->sysdata;
/* Host PCI controller */ if (pbus->self) {
node = pbm->op->dev.of_node;
/* PCI->PCI bridge */
node = pbus->self->dev.of_node;
} else {
struct pci_pbm_info *pbm = pbus->sysdata;
/* Host PCI controller */
node = pbm->op->dev.of_node;
}
pci_bus_slot_names(node, pbus);
} }
pci_bus_slot_names(node, pbus);
} }
return 0; return 0;

View file

@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
} }
} }
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
struct sun4v_2insn_patch_entry *end)
{
while (start < end) {
unsigned long addr = start->addr;
*(unsigned int *) (addr + 0) = start->insns[0];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 0));
*(unsigned int *) (addr + 4) = start->insns[1];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 4));
start++;
}
}
static void __init sun4v_patch(void) static void __init sun4v_patch(void)
{ {
extern void sun4v_hvapi_init(void); extern void sun4v_hvapi_init(void);
@ -267,6 +285,9 @@ static void __init sun4v_patch(void)
sun4v_patch_2insn_range(&__sun4v_2insn_patch, sun4v_patch_2insn_range(&__sun4v_2insn_patch,
&__sun4v_2insn_patch_end); &__sun4v_2insn_patch_end);
if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7)
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
&__sun_m7_2insn_patch_end);
sun4v_hvapi_init(); sun4v_hvapi_init();
} }

View file

@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
cpumask_t cpu_core_map[NR_CPUS] __read_mostly = cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE }; { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
[0 ... NR_CPUS-1] = CPU_MASK_NONE };
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map); EXPORT_SYMBOL(cpu_core_map);
EXPORT_SYMBOL(cpu_core_sib_map);
static cpumask_t smp_commenced_mask; static cpumask_t smp_commenced_mask;
@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void)
} }
} }
for_each_present_cpu(i) {
unsigned int j;
for_each_present_cpu(j) {
if (cpu_data(i).sock_id == cpu_data(j).sock_id)
cpumask_set_cpu(j, &cpu_core_sib_map[i]);
}
}
for_each_present_cpu(i) { for_each_present_cpu(i) {
unsigned int j; unsigned int j;

View file

@ -138,6 +138,11 @@ SECTIONS
*(.pause_3insn_patch) *(.pause_3insn_patch)
__pause_3insn_patch_end = .; __pause_3insn_patch_end = .;
} }
.sun_m7_2insn_patch : {
__sun_m7_2insn_patch = .;
*(.sun_m7_2insn_patch)
__sun_m7_2insn_patch_end = .;
}
PERCPU_SECTION(SMP_CACHE_BYTES) PERCPU_SECTION(SMP_CACHE_BYTES)
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);

View file

@ -54,6 +54,7 @@
#include "init_64.h" #include "init_64.h"
unsigned long kern_linear_pte_xor[4] __read_mostly; unsigned long kern_linear_pte_xor[4] __read_mostly;
static unsigned long page_cache4v_flag;
/* A bitmap, two bits for every 256MB of physical memory. These two /* A bitmap, two bits for every 256MB of physical memory. These two
* bits determine what page size we use for kernel linear * bits determine what page size we use for kernel linear
@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void)
static void __init sun4v_linear_pte_xor_finalize(void) static void __init sun4v_linear_pte_xor_finalize(void)
{ {
unsigned long pagecv_flag;
/* Bit 9 of TTE is no longer CV bit on M7 processor and it instead
* enables MCD error. Do not set bit 9 on M7 processor.
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
pagecv_flag = 0x00;
break;
default:
pagecv_flag = _PAGE_CV_4V;
break;
}
#ifndef CONFIG_DEBUG_PAGEALLOC #ifndef CONFIG_DEBUG_PAGEALLOC
if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) {
kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[1] = kern_linear_pte_xor[0]; kern_linear_pte_xor[1] = kern_linear_pte_xor[0];
@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) {
kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[2] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[2] = kern_linear_pte_xor[1]; kern_linear_pte_xor[2] = kern_linear_pte_xor[1];
@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) {
kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[3] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[3] = kern_linear_pte_xor[2]; kern_linear_pte_xor[3] = kern_linear_pte_xor[2];
@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void)
return available; return available;
} }
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
/* We need to exclude reserved regions. This exclusion will include /* We need to exclude reserved regions. This exclusion will include
* vmlinux and initrd. To be more precise the initrd size could be used to * vmlinux and initrd. To be more precise the initrd size could be used to
* compute a new lower limit because it is freed later during initialization. * compute a new lower limit because it is freed later during initialization.
@ -2034,6 +2055,25 @@ void __init paging_init(void)
memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
#endif #endif
/* TTE.cv bit on sparc v9 occupies the same position as TTE.mcde
* bit on M7 processor. This is a conflicting usage of the same
* bit. Enabling TTE.cv on M7 would turn on Memory Corruption
* Detection error on all pages and this will lead to problems
* later. Kernel does not run with MCD enabled and hence rest
* of the required steps to fully configure memory corruption
* detection are not taken. We need to ensure TTE.mcde is not
* set on M7 processor. Compute the value of cacheability
* flag for use later taking this into consideration.
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
page_cache4v_flag = _PAGE_CP_4V;
break;
default:
page_cache4v_flag = _PAGE_CACHE_4V;
break;
}
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
sun4v_pgprot_init(); sun4v_pgprot_init();
else else
@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end)
} }
#endif #endif
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
pgprot_t PAGE_KERNEL __read_mostly; pgprot_t PAGE_KERNEL __read_mostly;
EXPORT_SYMBOL(PAGE_KERNEL); EXPORT_SYMBOL(PAGE_KERNEL);
@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
_PAGE_P_4U | _PAGE_W_4U); _PAGE_P_4U | _PAGE_W_4U);
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
_PAGE_CP_4V | _PAGE_CV_4V | page_cache4v_flag | _PAGE_P_4V | _PAGE_W_4V);
_PAGE_P_4V | _PAGE_W_4V);
pte_base |= _PAGE_PMD_HUGE; pte_base |= _PAGE_PMD_HUGE;
@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void)
int i; int i;
PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID | PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID |
_PAGE_CACHE_4V | _PAGE_P_4V | page_cache4v_flag | _PAGE_P_4V |
__ACCESS_BITS_4V | __DIRTY_BITS_4V | __ACCESS_BITS_4V | __DIRTY_BITS_4V |
_PAGE_EXEC_4V); _PAGE_EXEC_4V);
PAGE_KERNEL_LOCKED = PAGE_KERNEL; PAGE_KERNEL_LOCKED = PAGE_KERNEL;
_PAGE_IE = _PAGE_IE_4V; _PAGE_IE = _PAGE_IE_4V;
_PAGE_E = _PAGE_E_4V; _PAGE_E = _PAGE_E_4V;
_PAGE_CACHE = _PAGE_CACHE_4V; _PAGE_CACHE = page_cache4v_flag;
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET;
@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void)
kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
#endif #endif
kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[0] |= (page_cache4v_flag | _PAGE_P_4V |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_W_4V);
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void)
_PAGE_SZ4MB_4V | _PAGE_SZ512K_4V | _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V |
_PAGE_SZ64K_4V | _PAGE_SZ8K_4V); _PAGE_SZ64K_4V | _PAGE_SZ8K_4V);
page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | _PAGE_CACHE_4V; page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | page_cache4v_flag;
page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V);
page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_EXEC_4V);
page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_EXEC_4V);
page_exec_bit = _PAGE_EXEC_4V; page_exec_bit = _PAGE_EXEC_4V;
@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr)
_PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U); _PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U);
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
val = (_PAGE_VALID | _PAGE_SZ4MB_4V | val = (_PAGE_VALID | _PAGE_SZ4MB_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | page_cache4v_flag | _PAGE_P_4V |
_PAGE_EXEC_4V | _PAGE_W_4V); _PAGE_EXEC_4V | _PAGE_W_4V);
return val | paddr; return val | paddr;

View file

@ -2,15 +2,14 @@
#define BOOT_COMPRESSED_MISC_H #define BOOT_COMPRESSED_MISC_H
/* /*
* we have to be careful, because no indirections are allowed here, and * Special hack: we have to be careful, because no indirections are allowed here,
* paravirt_ops is a kind of one. As it will only run in baremetal anyway, * and paravirt_ops is a kind of one. As it will only run in baremetal anyway,
* we just keep it from happening * we just keep it from happening. (This list needs to be extended when new
* paravirt and debugging variants are added.)
*/ */
#undef CONFIG_PARAVIRT #undef CONFIG_PARAVIRT
#undef CONFIG_PARAVIRT_SPINLOCKS
#undef CONFIG_KASAN #undef CONFIG_KASAN
#ifdef CONFIG_X86_32
#define _ASM_X86_DESC_H 1
#endif
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/screen_info.h> #include <linux/screen_info.h>

View file

@ -207,6 +207,7 @@ union kvm_mmu_page_role {
unsigned nxe:1; unsigned nxe:1;
unsigned cr0_wp:1; unsigned cr0_wp:1;
unsigned smep_andnot_wp:1; unsigned smep_andnot_wp:1;
unsigned smap_andnot_wp:1;
}; };
}; };
@ -400,6 +401,7 @@ struct kvm_vcpu_arch {
struct kvm_mmu_memory_cache mmu_page_header_cache; struct kvm_mmu_memory_cache mmu_page_header_cache;
struct fpu guest_fpu; struct fpu guest_fpu;
bool eager_fpu;
u64 xcr0; u64 xcr0;
u64 guest_supported_xcr0; u64 guest_supported_xcr0;
u32 guest_xstate_size; u32 guest_xstate_size;
@ -743,6 +745,7 @@ struct kvm_x86_ops {
void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
void (*fpu_activate)(struct kvm_vcpu *vcpu);
void (*fpu_deactivate)(struct kvm_vcpu *vcpu); void (*fpu_deactivate)(struct kvm_vcpu *vcpu);
void (*tlb_flush)(struct kvm_vcpu *vcpu); void (*tlb_flush)(struct kvm_vcpu *vcpu);

View file

@ -107,7 +107,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
static inline int user_mode(struct pt_regs *regs) static inline int user_mode(struct pt_regs *regs)
{ {
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
#else #else
return !!(regs->cs & 3); return !!(regs->cs & 3);
#endif #endif

View file

@ -231,11 +231,21 @@
#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8)
#ifdef __KERNEL__ #ifdef __KERNEL__
/*
* early_idt_handler_array is an array of entry points referenced in the
* early IDT. For simplicity, it's a real array with one entry point
* every nine bytes. That leaves room for an optional 'push $0' if the
* vector has no error code (two bytes), a 'push $vector_number' (two
* bytes), and a jump to the common entry code (up to five bytes).
*/
#define EARLY_IDT_HANDLER_SIZE 9
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];
#ifdef CONFIG_TRACING #ifdef CONFIG_TRACING
# define trace_early_idt_handlers early_idt_handlers # define trace_early_idt_handler_array early_idt_handler_array
#endif #endif
/* /*

View file

@ -140,6 +140,7 @@
#define MSR_CORE_C3_RESIDENCY 0x000003fc #define MSR_CORE_C3_RESIDENCY 0x000003fc
#define MSR_CORE_C6_RESIDENCY 0x000003fd #define MSR_CORE_C6_RESIDENCY 0x000003fd
#define MSR_CORE_C7_RESIDENCY 0x000003fe #define MSR_CORE_C7_RESIDENCY 0x000003fe
#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
#define MSR_PKG_C2_RESIDENCY 0x0000060d #define MSR_PKG_C2_RESIDENCY 0x0000060d
#define MSR_PKG_C8_RESIDENCY 0x00000630 #define MSR_PKG_C8_RESIDENCY 0x00000630
#define MSR_PKG_C9_RESIDENCY 0x00000631 #define MSR_PKG_C9_RESIDENCY 0x00000631

View file

@ -708,6 +708,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
struct pt_regs *regs) struct pt_regs *regs)
{ {
int i, ret = 0; int i, ret = 0;
char *tmp;
for (i = 0; i < mca_cfg.banks; i++) { for (i = 0; i < mca_cfg.banks; i++) {
m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
@ -716,9 +717,11 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
if (quirk_no_way_out) if (quirk_no_way_out)
quirk_no_way_out(i, m, regs); quirk_no_way_out(i, m, regs);
} }
if (mce_severity(m, mca_cfg.tolerant, msg, true) >=
MCE_PANIC_SEVERITY) if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) {
*msg = tmp;
ret = 1; ret = 1;
}
} }
return ret; return ret;
} }

View file

@ -190,6 +190,7 @@ static bool check_hw_exists(void)
u64 val, val_fail, val_new= ~0; u64 val, val_fail, val_new= ~0;
int i, reg, reg_fail, ret = 0; int i, reg, reg_fail, ret = 0;
int bios_fail = 0; int bios_fail = 0;
int reg_safe = -1;
/* /*
* Check to see if the BIOS enabled any of the counters, if so * Check to see if the BIOS enabled any of the counters, if so
@ -204,6 +205,8 @@ static bool check_hw_exists(void)
bios_fail = 1; bios_fail = 1;
val_fail = val; val_fail = val;
reg_fail = reg; reg_fail = reg;
} else {
reg_safe = i;
} }
} }
@ -221,12 +224,23 @@ static bool check_hw_exists(void)
} }
} }
/*
* If all the counters are enabled, the below test will always
* fail. The tools will also become useless in this scenario.
* Just fail and disable the hardware counters.
*/
if (reg_safe == -1) {
reg = reg_safe;
goto msr_fail;
}
/* /*
* Read the current value, change it and read it back to see if it * Read the current value, change it and read it back to see if it
* matches, this is needed to detect certain hardware emulators * matches, this is needed to detect certain hardware emulators
* (qemu/kvm) that don't trap on the MSR access and always return 0s. * (qemu/kvm) that don't trap on the MSR access and always return 0s.
*/ */
reg = x86_pmu_event_addr(0); reg = x86_pmu_event_addr(reg_safe);
if (rdmsrl_safe(reg, &val)) if (rdmsrl_safe(reg, &val))
goto msr_fail; goto msr_fail;
val ^= 0xffffUL; val ^= 0xffffUL;
@ -611,6 +625,7 @@ struct sched_state {
int event; /* event index */ int event; /* event index */
int counter; /* counter index */ int counter; /* counter index */
int unassigned; /* number of events to be assigned left */ int unassigned; /* number of events to be assigned left */
int nr_gp; /* number of GP counters used */
unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
}; };
@ -620,27 +635,29 @@ struct sched_state {
struct perf_sched { struct perf_sched {
int max_weight; int max_weight;
int max_events; int max_events;
struct perf_event **events; int max_gp;
struct sched_state state;
int saved_states; int saved_states;
struct event_constraint **constraints;
struct sched_state state;
struct sched_state saved[SCHED_STATES_MAX]; struct sched_state saved[SCHED_STATES_MAX];
}; };
/* /*
* Initialize interator that runs through all events and counters. * Initialize interator that runs through all events and counters.
*/ */
static void perf_sched_init(struct perf_sched *sched, struct perf_event **events, static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints,
int num, int wmin, int wmax) int num, int wmin, int wmax, int gpmax)
{ {
int idx; int idx;
memset(sched, 0, sizeof(*sched)); memset(sched, 0, sizeof(*sched));
sched->max_events = num; sched->max_events = num;
sched->max_weight = wmax; sched->max_weight = wmax;
sched->events = events; sched->max_gp = gpmax;
sched->constraints = constraints;
for (idx = 0; idx < num; idx++) { for (idx = 0; idx < num; idx++) {
if (events[idx]->hw.constraint->weight == wmin) if (constraints[idx]->weight == wmin)
break; break;
} }
@ -687,7 +704,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
if (sched->state.event >= sched->max_events) if (sched->state.event >= sched->max_events)
return false; return false;
c = sched->events[sched->state.event]->hw.constraint; c = sched->constraints[sched->state.event];
/* Prefer fixed purpose counters */ /* Prefer fixed purpose counters */
if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
idx = INTEL_PMC_IDX_FIXED; idx = INTEL_PMC_IDX_FIXED;
@ -696,11 +713,16 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
goto done; goto done;
} }
} }
/* Grab the first unused counter starting with idx */ /* Grab the first unused counter starting with idx */
idx = sched->state.counter; idx = sched->state.counter;
for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
if (!__test_and_set_bit(idx, sched->state.used)) if (!__test_and_set_bit(idx, sched->state.used)) {
if (sched->state.nr_gp++ >= sched->max_gp)
return false;
goto done; goto done;
}
} }
return false; return false;
@ -745,7 +767,7 @@ static bool perf_sched_next_event(struct perf_sched *sched)
if (sched->state.weight > sched->max_weight) if (sched->state.weight > sched->max_weight)
return false; return false;
} }
c = sched->events[sched->state.event]->hw.constraint; c = sched->constraints[sched->state.event];
} while (c->weight != sched->state.weight); } while (c->weight != sched->state.weight);
sched->state.counter = 0; /* start with first counter */ sched->state.counter = 0; /* start with first counter */
@ -756,12 +778,12 @@ static bool perf_sched_next_event(struct perf_sched *sched)
/* /*
* Assign a counter for each event. * Assign a counter for each event.
*/ */
int perf_assign_events(struct perf_event **events, int n, int perf_assign_events(struct event_constraint **constraints, int n,
int wmin, int wmax, int *assign) int wmin, int wmax, int gpmax, int *assign)
{ {
struct perf_sched sched; struct perf_sched sched;
perf_sched_init(&sched, events, n, wmin, wmax); perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
do { do {
if (!perf_sched_find_counter(&sched)) if (!perf_sched_find_counter(&sched))
@ -788,9 +810,9 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
x86_pmu.start_scheduling(cpuc); x86_pmu.start_scheduling(cpuc);
for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
hwc = &cpuc->event_list[i]->hw; cpuc->event_constraint[i] = NULL;
c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]);
hwc->constraint = c; cpuc->event_constraint[i] = c;
wmin = min(wmin, c->weight); wmin = min(wmin, c->weight);
wmax = max(wmax, c->weight); wmax = max(wmax, c->weight);
@ -801,7 +823,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
*/ */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
hwc = &cpuc->event_list[i]->hw; hwc = &cpuc->event_list[i]->hw;
c = hwc->constraint; c = cpuc->event_constraint[i];
/* never assigned */ /* never assigned */
if (hwc->idx == -1) if (hwc->idx == -1)
@ -821,9 +843,26 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
} }
/* slow path */ /* slow path */
if (i != n) if (i != n) {
unsched = perf_assign_events(cpuc->event_list, n, wmin, int gpmax = x86_pmu.num_counters;
wmax, assign);
/*
* Do not allow scheduling of more than half the available
* generic counters.
*
* This helps avoid counter starvation of sibling thread by
* ensuring at most half the counters cannot be in exclusive
* mode. There is no designated counters for the limits. Any
* N/2 counters can be used. This helps with events with
* specific counter constraints.
*/
if (is_ht_workaround_enabled() && !cpuc->is_fake &&
READ_ONCE(cpuc->excl_cntrs->exclusive_present))
gpmax /= 2;
unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
wmax, gpmax, assign);
}
/* /*
* In case of success (unsched = 0), mark events as committed, * In case of success (unsched = 0), mark events as committed,
@ -840,7 +879,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
e = cpuc->event_list[i]; e = cpuc->event_list[i];
e->hw.flags |= PERF_X86_EVENT_COMMITTED; e->hw.flags |= PERF_X86_EVENT_COMMITTED;
if (x86_pmu.commit_scheduling) if (x86_pmu.commit_scheduling)
x86_pmu.commit_scheduling(cpuc, e, assign[i]); x86_pmu.commit_scheduling(cpuc, i, assign[i]);
} }
} }
@ -1292,8 +1331,10 @@ static void x86_pmu_del(struct perf_event *event, int flags)
x86_pmu.put_event_constraints(cpuc, event); x86_pmu.put_event_constraints(cpuc, event);
/* Delete the array entry. */ /* Delete the array entry. */
while (++i < cpuc->n_events) while (++i < cpuc->n_events) {
cpuc->event_list[i-1] = cpuc->event_list[i]; cpuc->event_list[i-1] = cpuc->event_list[i];
cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
}
--cpuc->n_events; --cpuc->n_events;
perf_event_update_userpage(event); perf_event_update_userpage(event);

View file

@ -74,6 +74,7 @@ struct event_constraint {
#define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */ #define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */
#define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */ #define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */
#define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */
#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */
struct amd_nb { struct amd_nb {
@ -134,8 +135,6 @@ enum intel_excl_state_type {
struct intel_excl_states { struct intel_excl_states {
enum intel_excl_state_type init_state[X86_PMC_IDX_MAX]; enum intel_excl_state_type init_state[X86_PMC_IDX_MAX];
enum intel_excl_state_type state[X86_PMC_IDX_MAX]; enum intel_excl_state_type state[X86_PMC_IDX_MAX];
int num_alloc_cntrs;/* #counters allocated */
int max_alloc_cntrs;/* max #counters allowed */
bool sched_started; /* true if scheduling has started */ bool sched_started; /* true if scheduling has started */
}; };
@ -144,6 +143,11 @@ struct intel_excl_cntrs {
struct intel_excl_states states[2]; struct intel_excl_states states[2];
union {
u16 has_exclusive[2];
u32 exclusive_present;
};
int refcnt; /* per-core: #HT threads */ int refcnt; /* per-core: #HT threads */
unsigned core_id; /* per-core: core id */ unsigned core_id; /* per-core: core id */
}; };
@ -172,7 +176,11 @@ struct cpu_hw_events {
added in the current transaction */ added in the current transaction */
int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
u64 tags[X86_PMC_IDX_MAX]; u64 tags[X86_PMC_IDX_MAX];
struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
struct event_constraint *event_constraint[X86_PMC_IDX_MAX];
int n_excl; /* the number of exclusive events */
unsigned int group_flag; unsigned int group_flag;
int is_fake; int is_fake;
@ -519,9 +527,7 @@ struct x86_pmu {
void (*put_event_constraints)(struct cpu_hw_events *cpuc, void (*put_event_constraints)(struct cpu_hw_events *cpuc,
struct perf_event *event); struct perf_event *event);
void (*commit_scheduling)(struct cpu_hw_events *cpuc, void (*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr);
struct perf_event *event,
int cntr);
void (*start_scheduling)(struct cpu_hw_events *cpuc); void (*start_scheduling)(struct cpu_hw_events *cpuc);
@ -717,8 +723,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
void x86_pmu_enable_all(int added); void x86_pmu_enable_all(int added);
int perf_assign_events(struct perf_event **events, int n, int perf_assign_events(struct event_constraint **constraints, int n,
int wmin, int wmax, int *assign); int wmin, int wmax, int gpmax, int *assign);
int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
void x86_pmu_stop(struct perf_event *event, int flags); void x86_pmu_stop(struct perf_event *event, int flags);
@ -929,4 +935,8 @@ static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
return NULL; return NULL;
} }
static inline int is_ht_workaround_enabled(void)
{
return 0;
}
#endif /* CONFIG_CPU_SUP_INTEL */ #endif /* CONFIG_CPU_SUP_INTEL */

View file

@ -1923,7 +1923,6 @@ intel_start_scheduling(struct cpu_hw_events *cpuc)
xl = &excl_cntrs->states[tid]; xl = &excl_cntrs->states[tid];
xl->sched_started = true; xl->sched_started = true;
xl->num_alloc_cntrs = 0;
/* /*
* lock shared state until we are done scheduling * lock shared state until we are done scheduling
* in stop_event_scheduling() * in stop_event_scheduling()
@ -2000,6 +1999,11 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
* across HT threads * across HT threads
*/ */
is_excl = c->flags & PERF_X86_EVENT_EXCL; is_excl = c->flags & PERF_X86_EVENT_EXCL;
if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) {
event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT;
if (!cpuc->n_excl++)
WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1);
}
/* /*
* xl = state of current HT * xl = state of current HT
@ -2008,18 +2012,6 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
xl = &excl_cntrs->states[tid]; xl = &excl_cntrs->states[tid];
xlo = &excl_cntrs->states[o_tid]; xlo = &excl_cntrs->states[o_tid];
/*
* do not allow scheduling of more than max_alloc_cntrs
* which is set to half the available generic counters.
* this helps avoid counter starvation of sibling thread
* by ensuring at most half the counters cannot be in
* exclusive mode. There is not designated counters for the
* limits. Any N/2 counters can be used. This helps with
* events with specifix counter constraints
*/
if (xl->num_alloc_cntrs++ == xl->max_alloc_cntrs)
return &emptyconstraint;
cx = c; cx = c;
/* /*
@ -2106,7 +2098,7 @@ static struct event_constraint *
intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
struct perf_event *event) struct perf_event *event)
{ {
struct event_constraint *c1 = event->hw.constraint; struct event_constraint *c1 = cpuc->event_constraint[idx];
struct event_constraint *c2; struct event_constraint *c2;
/* /*
@ -2150,6 +2142,11 @@ static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
xl = &excl_cntrs->states[tid]; xl = &excl_cntrs->states[tid];
xlo = &excl_cntrs->states[o_tid]; xlo = &excl_cntrs->states[o_tid];
if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) {
hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT;
if (!--cpuc->n_excl)
WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0);
}
/* /*
* put_constraint may be called from x86_schedule_events() * put_constraint may be called from x86_schedule_events()
@ -2188,8 +2185,6 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
static void intel_put_event_constraints(struct cpu_hw_events *cpuc, static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
struct perf_event *event) struct perf_event *event)
{ {
struct event_constraint *c = event->hw.constraint;
intel_put_shared_regs_event_constraints(cpuc, event); intel_put_shared_regs_event_constraints(cpuc, event);
/* /*
@ -2197,19 +2192,14 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
* all events are subject to and must call the * all events are subject to and must call the
* put_excl_constraints() routine * put_excl_constraints() routine
*/ */
if (c && cpuc->excl_cntrs) if (cpuc->excl_cntrs)
intel_put_excl_constraints(cpuc, event); intel_put_excl_constraints(cpuc, event);
/* cleanup dynamic constraint */
if (c && (c->flags & PERF_X86_EVENT_DYNAMIC))
event->hw.constraint = NULL;
} }
static void intel_commit_scheduling(struct cpu_hw_events *cpuc, static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr)
struct perf_event *event, int cntr)
{ {
struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs; struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
struct event_constraint *c = event->hw.constraint; struct event_constraint *c = cpuc->event_constraint[idx];
struct intel_excl_states *xlo, *xl; struct intel_excl_states *xlo, *xl;
int tid = cpuc->excl_thread_id; int tid = cpuc->excl_thread_id;
int o_tid = 1 - tid; int o_tid = 1 - tid;
@ -2639,8 +2629,6 @@ static void intel_pmu_cpu_starting(int cpu)
cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR]; cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
int h = x86_pmu.num_counters >> 1;
for_each_cpu(i, topology_thread_cpumask(cpu)) { for_each_cpu(i, topology_thread_cpumask(cpu)) {
struct intel_excl_cntrs *c; struct intel_excl_cntrs *c;
@ -2654,11 +2642,6 @@ static void intel_pmu_cpu_starting(int cpu)
} }
cpuc->excl_cntrs->core_id = core_id; cpuc->excl_cntrs->core_id = core_id;
cpuc->excl_cntrs->refcnt++; cpuc->excl_cntrs->refcnt++;
/*
* set hard limit to half the number of generic counters
*/
cpuc->excl_cntrs->states[0].max_alloc_cntrs = h;
cpuc->excl_cntrs->states[1].max_alloc_cntrs = h;
} }
} }

View file

@ -706,9 +706,9 @@ void intel_pmu_pebs_disable(struct perf_event *event)
cpuc->pebs_enabled &= ~(1ULL << hwc->idx); cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_LDLAT) if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32)); cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
else if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_ST) else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
cpuc->pebs_enabled &= ~(1ULL << 63); cpuc->pebs_enabled &= ~(1ULL << 63);
if (cpuc->enabled) if (cpuc->enabled)

View file

@ -151,7 +151,7 @@ static int __init pt_pmu_hw_init(void)
de_attr->attr.attr.name = pt_caps[i].name; de_attr->attr.attr.name = pt_caps[i].name;
sysfs_attr_init(&de_attrs->attr.attr); sysfs_attr_init(&de_attr->attr.attr);
de_attr->attr.attr.mode = S_IRUGO; de_attr->attr.attr.mode = S_IRUGO;
de_attr->attr.show = pt_cap_show; de_attr->attr.show = pt_cap_show;
@ -615,7 +615,8 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
struct perf_output_handle *handle) struct perf_output_handle *handle)
{ {
unsigned long idx, npages, end; unsigned long head = local64_read(&buf->head);
unsigned long idx, npages, wakeup;
if (buf->snapshot) if (buf->snapshot)
return 0; return 0;
@ -634,17 +635,26 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
buf->topa_index[buf->stop_pos]->stop = 0; buf->topa_index[buf->stop_pos]->stop = 0;
buf->topa_index[buf->intr_pos]->intr = 0; buf->topa_index[buf->intr_pos]->intr = 0;
if (pt_cap_get(PT_CAP_topa_multiple_entries)) { /* how many pages till the STOP marker */
npages = (handle->size + 1) >> PAGE_SHIFT; npages = handle->size >> PAGE_SHIFT;
end = (local64_read(&buf->head) >> PAGE_SHIFT) + npages;
/*if (end > handle->wakeup >> PAGE_SHIFT) /* if it's on a page boundary, fill up one more page */
end = handle->wakeup >> PAGE_SHIFT;*/ if (!offset_in_page(head + handle->size + 1))
idx = end & (buf->nr_pages - 1); npages++;
buf->stop_pos = idx;
idx = (local64_read(&buf->head) >> PAGE_SHIFT) + npages - 1; idx = (head >> PAGE_SHIFT) + npages;
idx &= buf->nr_pages - 1; idx &= buf->nr_pages - 1;
buf->intr_pos = idx; buf->stop_pos = idx;
}
wakeup = handle->wakeup >> PAGE_SHIFT;
/* in the worst case, wake up the consumer one page before hard stop */
idx = (head >> PAGE_SHIFT) + npages - 1;
if (idx > wakeup)
idx = wakeup;
idx &= buf->nr_pages - 1;
buf->intr_pos = idx;
buf->topa_index[buf->stop_pos]->stop = 1; buf->topa_index[buf->stop_pos]->stop = 1;
buf->topa_index[buf->intr_pos]->intr = 1; buf->topa_index[buf->intr_pos]->intr = 1;

View file

@ -365,9 +365,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int
bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
hwc = &box->event_list[i]->hw;
c = uncore_get_event_constraint(box, box->event_list[i]); c = uncore_get_event_constraint(box, box->event_list[i]);
hwc->constraint = c; box->event_constraint[i] = c;
wmin = min(wmin, c->weight); wmin = min(wmin, c->weight);
wmax = max(wmax, c->weight); wmax = max(wmax, c->weight);
} }
@ -375,7 +374,7 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int
/* fastpath, try to reuse previous register */ /* fastpath, try to reuse previous register */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
hwc = &box->event_list[i]->hw; hwc = &box->event_list[i]->hw;
c = hwc->constraint; c = box->event_constraint[i];
/* never assigned */ /* never assigned */
if (hwc->idx == -1) if (hwc->idx == -1)
@ -395,8 +394,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int
} }
/* slow path */ /* slow path */
if (i != n) if (i != n)
ret = perf_assign_events(box->event_list, n, ret = perf_assign_events(box->event_constraint, n,
wmin, wmax, assign); wmin, wmax, n, assign);
if (!assign || ret) { if (!assign || ret) {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)

View file

@ -97,6 +97,7 @@ struct intel_uncore_box {
atomic_t refcnt; atomic_t refcnt;
struct perf_event *events[UNCORE_PMC_IDX_MAX]; struct perf_event *events[UNCORE_PMC_IDX_MAX];
struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX];
unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
u64 tags[UNCORE_PMC_IDX_MAX]; u64 tags[UNCORE_PMC_IDX_MAX];
struct pci_dev *pci_dev; struct pci_dev *pci_dev;

View file

@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
clear_bss(); clear_bss();
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
set_intr_gate(i, early_idt_handlers[i]); set_intr_gate(i, early_idt_handler_array[i]);
load_idt((const struct desc_ptr *)&idt_descr); load_idt((const struct desc_ptr *)&idt_descr);
copy_bootdata(__va(real_mode_data)); copy_bootdata(__va(real_mode_data));

View file

@ -478,21 +478,22 @@ is486:
__INIT __INIT
setup_once: setup_once:
/* /*
* Set up a idt with 256 entries pointing to ignore_int, * Set up a idt with 256 interrupt gates that push zero if there
* interrupt gates. It doesn't actually load idt - that needs * is no error code and then jump to early_idt_handler_common.
* to be done on each CPU. Interrupts are enabled elsewhere, * It doesn't actually load the idt - that needs to be done on
* when we can be relatively sure everything is ok. * each CPU. Interrupts are enabled elsewhere, when we can be
* relatively sure everything is ok.
*/ */
movl $idt_table,%edi movl $idt_table,%edi
movl $early_idt_handlers,%eax movl $early_idt_handler_array,%eax
movl $NUM_EXCEPTION_VECTORS,%ecx movl $NUM_EXCEPTION_VECTORS,%ecx
1: 1:
movl %eax,(%edi) movl %eax,(%edi)
movl %eax,4(%edi) movl %eax,4(%edi)
/* interrupt gate, dpl=0, present */ /* interrupt gate, dpl=0, present */
movl $(0x8E000000 + __KERNEL_CS),2(%edi) movl $(0x8E000000 + __KERNEL_CS),2(%edi)
addl $9,%eax addl $EARLY_IDT_HANDLER_SIZE,%eax
addl $8,%edi addl $8,%edi
loop 1b loop 1b
@ -524,26 +525,28 @@ setup_once:
andl $0,setup_once_ref /* Once is enough, thanks */ andl $0,setup_once_ref /* Once is enough, thanks */
ret ret
ENTRY(early_idt_handlers) ENTRY(early_idt_handler_array)
# 36(%esp) %eflags # 36(%esp) %eflags
# 32(%esp) %cs # 32(%esp) %cs
# 28(%esp) %eip # 28(%esp) %eip
# 24(%rsp) error code # 24(%rsp) error code
i = 0 i = 0
.rept NUM_EXCEPTION_VECTORS .rept NUM_EXCEPTION_VECTORS
.if (EXCEPTION_ERRCODE_MASK >> i) & 1 .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
ASM_NOP2
.else
pushl $0 # Dummy error code, to make stack frame uniform pushl $0 # Dummy error code, to make stack frame uniform
.endif .endif
pushl $i # 20(%esp) Vector number pushl $i # 20(%esp) Vector number
jmp early_idt_handler jmp early_idt_handler_common
i = i + 1 i = i + 1
.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
.endr .endr
ENDPROC(early_idt_handlers) ENDPROC(early_idt_handler_array)
/* This is global to keep gas from relaxing the jumps */ early_idt_handler_common:
ENTRY(early_idt_handler) /*
* The stack is the hardware frame, an error code or zero, and the
* vector number.
*/
cld cld
cmpl $2,(%esp) # X86_TRAP_NMI cmpl $2,(%esp) # X86_TRAP_NMI
@ -603,7 +606,7 @@ ex_entry:
is_nmi: is_nmi:
addl $8,%esp /* drop vector number and error code */ addl $8,%esp /* drop vector number and error code */
iret iret
ENDPROC(early_idt_handler) ENDPROC(early_idt_handler_common)
/* This is the default interrupt "handler" :-) */ /* This is the default interrupt "handler" :-) */
ALIGN ALIGN

View file

@ -321,26 +321,28 @@ bad_address:
jmp bad_address jmp bad_address
__INIT __INIT
.globl early_idt_handlers ENTRY(early_idt_handler_array)
early_idt_handlers:
# 104(%rsp) %rflags # 104(%rsp) %rflags
# 96(%rsp) %cs # 96(%rsp) %cs
# 88(%rsp) %rip # 88(%rsp) %rip
# 80(%rsp) error code # 80(%rsp) error code
i = 0 i = 0
.rept NUM_EXCEPTION_VECTORS .rept NUM_EXCEPTION_VECTORS
.if (EXCEPTION_ERRCODE_MASK >> i) & 1 .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
ASM_NOP2
.else
pushq $0 # Dummy error code, to make stack frame uniform pushq $0 # Dummy error code, to make stack frame uniform
.endif .endif
pushq $i # 72(%rsp) Vector number pushq $i # 72(%rsp) Vector number
jmp early_idt_handler jmp early_idt_handler_common
i = i + 1 i = i + 1
.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
.endr .endr
ENDPROC(early_idt_handler_array)
/* This is global to keep gas from relaxing the jumps */ early_idt_handler_common:
ENTRY(early_idt_handler) /*
* The stack is the hardware frame, an error code or zero, and the
* vector number.
*/
cld cld
cmpl $2,(%rsp) # X86_TRAP_NMI cmpl $2,(%rsp) # X86_TRAP_NMI
@ -412,7 +414,7 @@ ENTRY(early_idt_handler)
is_nmi: is_nmi:
addq $16,%rsp # drop vector number and error code addq $16,%rsp # drop vector number and error code
INTERRUPT_RETURN INTERRUPT_RETURN
ENDPROC(early_idt_handler) ENDPROC(early_idt_handler_common)
__INITDATA __INITDATA

View file

@ -173,6 +173,21 @@ static void init_thread_xstate(void)
xstate_size = sizeof(struct i387_fxsave_struct); xstate_size = sizeof(struct i387_fxsave_struct);
else else
xstate_size = sizeof(struct i387_fsave_struct); xstate_size = sizeof(struct i387_fsave_struct);
/*
* Quirk: we don't yet handle the XSAVES* instructions
* correctly, as we don't correctly convert between
* standard and compacted format when interfacing
* with user-space - so disable it for now.
*
* The difference is small: with recent CPUs the
* compacted format is only marginally smaller than
* the standard FPU state format.
*
* ( This is easy to backport while we are fixing
* XSAVES* support. )
*/
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
} }
/* /*

View file

@ -16,6 +16,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/i387.h> /* For use_eager_fpu. Ugh! */
#include <asm/fpu-internal.h> /* For use_eager_fpu. Ugh! */
#include <asm/user.h> #include <asm/user.h>
#include <asm/xsave.h> #include <asm/xsave.h>
#include "cpuid.h" #include "cpuid.h"
@ -95,6 +97,8 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
best->ebx = xstate_required_size(vcpu->arch.xcr0, true); best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
vcpu->arch.eager_fpu = guest_cpuid_has_mpx(vcpu);
/* /*
* The existing code assumes virtual address is 48-bit in the canonical * The existing code assumes virtual address is 48-bit in the canonical
* address checks; exit if it is ever changed. * address checks; exit if it is ever changed.

View file

@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
best = kvm_find_cpuid_entry(vcpu, 7, 0); best = kvm_find_cpuid_entry(vcpu, 7, 0);
return best && (best->ebx & bit(X86_FEATURE_RTM)); return best && (best->ebx & bit(X86_FEATURE_RTM));
} }
static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
best = kvm_find_cpuid_entry(vcpu, 7, 0);
return best && (best->ebx & bit(X86_FEATURE_MPX));
}
#endif #endif

View file

@ -3736,8 +3736,8 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
} }
} }
void update_permission_bitmask(struct kvm_vcpu *vcpu, static void update_permission_bitmask(struct kvm_vcpu *vcpu,
struct kvm_mmu *mmu, bool ept) struct kvm_mmu *mmu, bool ept)
{ {
unsigned bit, byte, pfec; unsigned bit, byte, pfec;
u8 map; u8 map;
@ -3918,6 +3918,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu) void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu)
{ {
bool smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); bool smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
bool smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP);
struct kvm_mmu *context = &vcpu->arch.mmu; struct kvm_mmu *context = &vcpu->arch.mmu;
MMU_WARN_ON(VALID_PAGE(context->root_hpa)); MMU_WARN_ON(VALID_PAGE(context->root_hpa));
@ -3936,6 +3937,8 @@ void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu)
context->base_role.cr0_wp = is_write_protection(vcpu); context->base_role.cr0_wp = is_write_protection(vcpu);
context->base_role.smep_andnot_wp context->base_role.smep_andnot_wp
= smep && !is_write_protection(vcpu); = smep && !is_write_protection(vcpu);
context->base_role.smap_andnot_wp
= smap && !is_write_protection(vcpu);
} }
EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu); EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu);
@ -4207,12 +4210,18 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
const u8 *new, int bytes) const u8 *new, int bytes)
{ {
gfn_t gfn = gpa >> PAGE_SHIFT; gfn_t gfn = gpa >> PAGE_SHIFT;
union kvm_mmu_page_role mask = { .word = 0 };
struct kvm_mmu_page *sp; struct kvm_mmu_page *sp;
LIST_HEAD(invalid_list); LIST_HEAD(invalid_list);
u64 entry, gentry, *spte; u64 entry, gentry, *spte;
int npte; int npte;
bool remote_flush, local_flush, zap_page; bool remote_flush, local_flush, zap_page;
union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
.cr0_wp = 1,
.cr4_pae = 1,
.nxe = 1,
.smep_andnot_wp = 1,
.smap_andnot_wp = 1,
};
/* /*
* If we don't have indirect shadow pages, it means no page is * If we don't have indirect shadow pages, it means no page is
@ -4238,7 +4247,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
++vcpu->kvm->stat.mmu_pte_write; ++vcpu->kvm->stat.mmu_pte_write;
kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE); kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
mask.cr0_wp = mask.cr4_pae = mask.nxe = 1;
for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) { for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
if (detect_write_misaligned(sp, gpa, bytes) || if (detect_write_misaligned(sp, gpa, bytes) ||
detect_write_flooding(sp)) { detect_write_flooding(sp)) {

View file

@ -71,8 +71,6 @@ enum {
int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu); void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu);
void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly); void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly);
void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
bool ept);
static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
{ {
@ -166,6 +164,8 @@ static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
int index = (pfec >> 1) + int index = (pfec >> 1) +
(smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1));
WARN_ON(pfec & PFERR_RSVD_MASK);
return (mmu->permissions[index] >> pte_access) & 1; return (mmu->permissions[index] >> pte_access) & 1;
} }

View file

@ -718,6 +718,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
mmu_is_nested(vcpu)); mmu_is_nested(vcpu));
if (likely(r != RET_MMIO_PF_INVALID)) if (likely(r != RET_MMIO_PF_INVALID))
return r; return r;
/*
* page fault with PFEC.RSVD = 1 is caused by shadow
* page fault, should not be used to walk guest page
* table.
*/
error_code &= ~PFERR_RSVD_MASK;
}; };
r = mmu_topup_memory_caches(vcpu); r = mmu_topup_memory_caches(vcpu);

Some files were not shown because too many files have changed in this diff Show more