mirror of https://gitee.com/openkylin/linux.git
Merge branch 'machtypes' into orion
This commit is contained in:
commit
fa6868508a
|
@ -84,10 +84,9 @@
|
||||||
runs an instance of gdb against the vmlinux file which contains
|
runs an instance of gdb against the vmlinux file which contains
|
||||||
the symbols (not boot image such as bzImage, zImage, uImage...).
|
the symbols (not boot image such as bzImage, zImage, uImage...).
|
||||||
In gdb the developer specifies the connection parameters and
|
In gdb the developer specifies the connection parameters and
|
||||||
connects to kgdb. Depending on which kgdb I/O modules exist in
|
connects to kgdb. The type of connection a developer makes with
|
||||||
the kernel for a given architecture, it may be possible to debug
|
gdb depends on the availability of kgdb I/O modules compiled as
|
||||||
the test machine's kernel with the development machine using a
|
builtin's or kernel modules in the test machine's kernel.
|
||||||
rs232 or ethernet connection.
|
|
||||||
</para>
|
</para>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="CompilingAKernel">
|
<chapter id="CompilingAKernel">
|
||||||
|
@ -223,7 +222,7 @@
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
IMPORTANT NOTE: Using this option with kgdb over the console
|
IMPORTANT NOTE: Using this option with kgdb over the console
|
||||||
(kgdboc) or kgdb over ethernet (kgdboe) is not supported.
|
(kgdboc) is not supported.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -249,18 +248,11 @@
|
||||||
(gdb) target remote /dev/ttyS0
|
(gdb) target remote /dev/ttyS0
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
Example (kgdb to a terminal server):
|
Example (kgdb to a terminal server on tcp port 2012):
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
% gdb ./vmlinux
|
% gdb ./vmlinux
|
||||||
(gdb) target remote udp:192.168.2.2:6443
|
(gdb) target remote 192.168.2.2:2012
|
||||||
</programlisting>
|
|
||||||
<para>
|
|
||||||
Example (kgdb over ethernet):
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
% gdb ./vmlinux
|
|
||||||
(gdb) target remote udp:192.168.2.2:6443
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
Once connected, you can debug a kernel the way you would debug an
|
Once connected, you can debug a kernel the way you would debug an
|
||||||
|
|
|
@ -2,17 +2,12 @@ Naming and data format standards for sysfs files
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
The libsensors library offers an interface to the raw sensors data
|
The libsensors library offers an interface to the raw sensors data
|
||||||
through the sysfs interface. See libsensors documentation and source for
|
through the sysfs interface. Since lm-sensors 3.0.0, libsensors is
|
||||||
further information. As of writing this document, libsensors
|
completely chip-independent. It assumes that all the kernel drivers
|
||||||
(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating
|
implement the standard sysfs interface described in this document.
|
||||||
support for any given chip requires modifying the library's code.
|
This makes adding or updating support for any given chip very easy, as
|
||||||
This is because libsensors was written for the procfs interface
|
libsensors, and applications using it, do not need to be modified.
|
||||||
older kernel modules were using, which wasn't standardized enough.
|
This is a major improvement compared to lm-sensors 2.
|
||||||
Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
|
|
||||||
support for the sysfs interface, though.
|
|
||||||
|
|
||||||
The new sysfs interface was designed to be as chip-independent as
|
|
||||||
possible.
|
|
||||||
|
|
||||||
Note that motherboards vary widely in the connections to sensor chips.
|
Note that motherboards vary widely in the connections to sensor chips.
|
||||||
There is no standard that ensures, for example, that the second
|
There is no standard that ensures, for example, that the second
|
||||||
|
@ -35,19 +30,17 @@ access this data in a simple and consistent way. That said, such programs
|
||||||
will have to implement conversion, labeling and hiding of inputs. For
|
will have to implement conversion, labeling and hiding of inputs. For
|
||||||
this reason, it is still not recommended to bypass the library.
|
this reason, it is still not recommended to bypass the library.
|
||||||
|
|
||||||
If you are developing a userspace application please send us feedback on
|
|
||||||
this standard.
|
|
||||||
|
|
||||||
Note that this standard isn't completely established yet, so it is subject
|
|
||||||
to changes. If you are writing a new hardware monitoring driver those
|
|
||||||
features can't seem to fit in this interface, please contact us with your
|
|
||||||
extension proposal. Keep in mind that backward compatibility must be
|
|
||||||
preserved.
|
|
||||||
|
|
||||||
Each chip gets its own directory in the sysfs /sys/devices tree. To
|
Each chip gets its own directory in the sysfs /sys/devices tree. To
|
||||||
find all sensor chips, it is easier to follow the device symlinks from
|
find all sensor chips, it is easier to follow the device symlinks from
|
||||||
/sys/class/hwmon/hwmon*.
|
/sys/class/hwmon/hwmon*.
|
||||||
|
|
||||||
|
Up to lm-sensors 3.0.0, libsensors looks for hardware monitoring attributes
|
||||||
|
in the "physical" device directory. Since lm-sensors 3.0.1, attributes found
|
||||||
|
in the hwmon "class" device directory are also supported. Complex drivers
|
||||||
|
(e.g. drivers for multifunction chips) may want to use this possibility to
|
||||||
|
avoid namespace pollution. The only drawback will be that older versions of
|
||||||
|
libsensors won't support the driver in question.
|
||||||
|
|
||||||
All sysfs values are fixed point numbers.
|
All sysfs values are fixed point numbers.
|
||||||
|
|
||||||
There is only one value per file, unlike the older /proc specification.
|
There is only one value per file, unlike the older /proc specification.
|
||||||
|
|
|
@ -4431,10 +4431,10 @@ M: johnpol@2ka.mipt.ru
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
W83791D HARDWARE MONITORING DRIVER
|
W83791D HARDWARE MONITORING DRIVER
|
||||||
P: Charles Spirakis
|
P: Marc Hulsman
|
||||||
M: bezaur@gmail.com
|
M: m.hulsman@tudelft.nl
|
||||||
L: lm-sensors@lm-sensors.org
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Odd Fixes
|
S: Maintained
|
||||||
|
|
||||||
W83793 HARDWARE MONITORING DRIVER
|
W83793 HARDWARE MONITORING DRIVER
|
||||||
P: Rudolf Marek
|
P: Rudolf Marek
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 26
|
SUBLEVEL = 26
|
||||||
EXTRAVERSION = -rc7
|
EXTRAVERSION = -rc8
|
||||||
NAME = Rotary Wombat
|
NAME = Rotary Wombat
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|
|
@ -13,6 +13,7 @@ NM := $(NM) -B
|
||||||
LDFLAGS_vmlinux := -static -N #-relax
|
LDFLAGS_vmlinux := -static -N #-relax
|
||||||
CHECKFLAGS += -D__alpha__ -m64
|
CHECKFLAGS += -D__alpha__ -m64
|
||||||
cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
|
cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
|
||||||
|
cflags-y += $(call cc-option, -fno-jump-tables)
|
||||||
|
|
||||||
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
|
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
|
||||||
cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
|
cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
|
||||||
|
|
|
@ -74,6 +74,8 @@
|
||||||
# define DBG(args)
|
# define DBG(args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DEFINE_SPINLOCK(t2_hae_lock);
|
||||||
|
|
||||||
static volatile unsigned int t2_mcheck_any_expected;
|
static volatile unsigned int t2_mcheck_any_expected;
|
||||||
static volatile unsigned int t2_mcheck_last_taken;
|
static volatile unsigned int t2_mcheck_last_taken;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_i
|
||||||
static void __init
|
static void __init
|
||||||
quirk_cypress(struct pci_dev *dev)
|
quirk_cypress(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
|
/* The Notorious Cy82C693 chip. */
|
||||||
|
|
||||||
|
/* The generic legacy mode IDE fixup in drivers/pci/probe.c
|
||||||
|
doesn't work correctly with the Cypress IDE controller as
|
||||||
|
it has non-standard register layout. Fix that. */
|
||||||
|
if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
|
||||||
|
dev->resource[2].start = dev->resource[3].start = 0;
|
||||||
|
dev->resource[2].end = dev->resource[3].end = 0;
|
||||||
|
dev->resource[2].flags = dev->resource[3].flags = 0;
|
||||||
|
if (PCI_FUNC(dev->devfn) == 2) {
|
||||||
|
dev->resource[0].start = 0x170;
|
||||||
|
dev->resource[0].end = 0x177;
|
||||||
|
dev->resource[1].start = 0x376;
|
||||||
|
dev->resource[1].end = 0x376;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The Cypress bridge responds on the PCI bus in the address range
|
/* The Cypress bridge responds on the PCI bus in the address range
|
||||||
0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no
|
0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no
|
||||||
way to turn this off. The bridge also supports several extended
|
way to turn this off. The bridge also supports several extended
|
||||||
|
|
|
@ -447,7 +447,7 @@ struct unaligned_stat {
|
||||||
|
|
||||||
|
|
||||||
/* Macro for exception fixup code to access integer registers. */
|
/* Macro for exception fixup code to access integer registers. */
|
||||||
#define una_reg(r) (regs->regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
|
#define una_reg(r) (_regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
|
||||||
|
|
||||||
|
|
||||||
asmlinkage void
|
asmlinkage void
|
||||||
|
@ -456,6 +456,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
|
||||||
{
|
{
|
||||||
long error, tmp1, tmp2, tmp3, tmp4;
|
long error, tmp1, tmp2, tmp3, tmp4;
|
||||||
unsigned long pc = regs->pc - 4;
|
unsigned long pc = regs->pc - 4;
|
||||||
|
unsigned long *_regs = regs->regs;
|
||||||
const struct exception_table_entry *fixup;
|
const struct exception_table_entry *fixup;
|
||||||
|
|
||||||
unaligned[0].count++;
|
unaligned[0].count++;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#
|
#
|
||||||
# http://www.arm.linux.org.uk/developer/machines/?action=new
|
# http://www.arm.linux.org.uk/developer/machines/?action=new
|
||||||
#
|
#
|
||||||
# Last update: Sat Apr 19 11:23:38 2008
|
# Last update: Mon Jul 7 16:25:39 2008
|
||||||
#
|
#
|
||||||
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
|
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
|
||||||
#
|
#
|
||||||
|
@ -560,7 +560,6 @@ husky MACH_HUSKY HUSKY 543
|
||||||
boxer MACH_BOXER BOXER 544
|
boxer MACH_BOXER BOXER 544
|
||||||
shepherd MACH_SHEPHERD SHEPHERD 545
|
shepherd MACH_SHEPHERD SHEPHERD 545
|
||||||
aml42800aa MACH_AML42800AA AML42800AA 546
|
aml42800aa MACH_AML42800AA AML42800AA 546
|
||||||
ml674001 MACH_MACH_TYPE_ML674001 MACH_TYPE_ML674001 547
|
|
||||||
lpc2294 MACH_LPC2294 LPC2294 548
|
lpc2294 MACH_LPC2294 LPC2294 548
|
||||||
switchgrass MACH_SWITCHGRASS SWITCHGRASS 549
|
switchgrass MACH_SWITCHGRASS SWITCHGRASS 549
|
||||||
ens_cmu MACH_ENS_CMU ENS_CMU 550
|
ens_cmu MACH_ENS_CMU ENS_CMU 550
|
||||||
|
@ -748,7 +747,6 @@ anubis MACH_ANUBIS ANUBIS 734
|
||||||
ite8152 MACH_ITE8152 ITE8152 735
|
ite8152 MACH_ITE8152 ITE8152 735
|
||||||
lpc3xxx MACH_LPC3XXX LPC3XXX 736
|
lpc3xxx MACH_LPC3XXX LPC3XXX 736
|
||||||
puppeteer MACH_PUPPETEER PUPPETEER 737
|
puppeteer MACH_PUPPETEER PUPPETEER 737
|
||||||
vt001 MACH_MACH_VADATECH MACH_VADATECH 738
|
|
||||||
e570 MACH_E570 E570 739
|
e570 MACH_E570 E570 739
|
||||||
x50 MACH_X50 X50 740
|
x50 MACH_X50 X50 740
|
||||||
recon MACH_RECON RECON 741
|
recon MACH_RECON RECON 741
|
||||||
|
@ -839,7 +837,7 @@ ccxp270 MACH_CCXP CCXP 825
|
||||||
omap_gsample MACH_OMAP_GSAMPLE OMAP_GSAMPLE 826
|
omap_gsample MACH_OMAP_GSAMPLE OMAP_GSAMPLE 826
|
||||||
realview_eb MACH_REALVIEW_EB REALVIEW_EB 827
|
realview_eb MACH_REALVIEW_EB REALVIEW_EB 827
|
||||||
samoa MACH_SAMOA SAMOA 828
|
samoa MACH_SAMOA SAMOA 828
|
||||||
t3xscale MACH_T3XSCALE T3XSCALE 829
|
palmt3 MACH_PALMT3 PALMT3 829
|
||||||
i878 MACH_I878 I878 830
|
i878 MACH_I878 I878 830
|
||||||
borzoi MACH_BORZOI BORZOI 831
|
borzoi MACH_BORZOI BORZOI 831
|
||||||
gecko MACH_GECKO GECKO 832
|
gecko MACH_GECKO GECKO 832
|
||||||
|
@ -895,7 +893,7 @@ mio8390 MACH_MIO8390 MIO8390 881
|
||||||
omi_board MACH_OMI_BOARD OMI_BOARD 882
|
omi_board MACH_OMI_BOARD OMI_BOARD 882
|
||||||
mx21civ MACH_MX21CIV MX21CIV 883
|
mx21civ MACH_MX21CIV MX21CIV 883
|
||||||
mahi_cdac MACH_MAHI_CDAC MAHI_CDAC 884
|
mahi_cdac MACH_MAHI_CDAC MAHI_CDAC 884
|
||||||
xscale_palmtx MACH_XSCALE_PALMTX XSCALE_PALMTX 885
|
palmtx MACH_PALMTX PALMTX 885
|
||||||
s3c2413 MACH_S3C2413 S3C2413 887
|
s3c2413 MACH_S3C2413 S3C2413 887
|
||||||
samsys_ep0 MACH_SAMSYS_EP0 SAMSYS_EP0 888
|
samsys_ep0 MACH_SAMSYS_EP0 SAMSYS_EP0 888
|
||||||
wg302v1 MACH_WG302V1 WG302V1 889
|
wg302v1 MACH_WG302V1 WG302V1 889
|
||||||
|
@ -918,7 +916,7 @@ nxdb500 MACH_NXDB500 NXDB500 905
|
||||||
apf9328 MACH_APF9328 APF9328 906
|
apf9328 MACH_APF9328 APF9328 906
|
||||||
omap_wipoq MACH_OMAP_WIPOQ OMAP_WIPOQ 907
|
omap_wipoq MACH_OMAP_WIPOQ OMAP_WIPOQ 907
|
||||||
omap_twip MACH_OMAP_TWIP OMAP_TWIP 908
|
omap_twip MACH_OMAP_TWIP OMAP_TWIP 908
|
||||||
xscale_treo650 MACH_XSCALE_PALMTREO650 XSCALE_PALMTREO650 909
|
palmtreo650 MACH_PALMTREO650 PALMTREO650 909
|
||||||
acumen MACH_ACUMEN ACUMEN 910
|
acumen MACH_ACUMEN ACUMEN 910
|
||||||
xp100 MACH_XP100 XP100 911
|
xp100 MACH_XP100 XP100 911
|
||||||
fs2410 MACH_FS2410 FS2410 912
|
fs2410 MACH_FS2410 FS2410 912
|
||||||
|
@ -926,8 +924,8 @@ pxa270_cerf MACH_PXA270_CERF PXA270_CERF 913
|
||||||
sq2ftlpalm MACH_SQ2FTLPALM SQ2FTLPALM 914
|
sq2ftlpalm MACH_SQ2FTLPALM SQ2FTLPALM 914
|
||||||
bsemserver MACH_BSEMSERVER BSEMSERVER 915
|
bsemserver MACH_BSEMSERVER BSEMSERVER 915
|
||||||
netclient MACH_NETCLIENT NETCLIENT 916
|
netclient MACH_NETCLIENT NETCLIENT 916
|
||||||
xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917
|
palmt5 MACH_PALMT5 PALMT5 917
|
||||||
xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918
|
palmtc MACH_PALMTC PALMTC 918
|
||||||
omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919
|
omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919
|
||||||
mxc30030evb MACH_MXC30030EVB MXC30030EVB 920
|
mxc30030evb MACH_MXC30030EVB MXC30030EVB 920
|
||||||
rea_2d MACH_REA_2D REA_2D 921
|
rea_2d MACH_REA_2D REA_2D 921
|
||||||
|
@ -1220,7 +1218,6 @@ empca400 MACH_EMPCA400 EMPCA400 1211
|
||||||
em7210 MACH_EM7210 EM7210 1212
|
em7210 MACH_EM7210 EM7210 1212
|
||||||
htchermes MACH_HTCHERMES HTCHERMES 1213
|
htchermes MACH_HTCHERMES HTCHERMES 1213
|
||||||
eti_c1 MACH_ETI_C1 ETI_C1 1214
|
eti_c1 MACH_ETI_C1 ETI_C1 1214
|
||||||
mach_dep2410 MACH_MACH_DEP2410 MACH_DEP2410 1215
|
|
||||||
ac100 MACH_AC100 AC100 1216
|
ac100 MACH_AC100 AC100 1216
|
||||||
sneetch MACH_SNEETCH SNEETCH 1217
|
sneetch MACH_SNEETCH SNEETCH 1217
|
||||||
studentmate MACH_STUDENTMATE STUDENTMATE 1218
|
studentmate MACH_STUDENTMATE STUDENTMATE 1218
|
||||||
|
@ -1421,10 +1418,10 @@ looxc550 MACH_LOOXC550 LOOXC550 1417
|
||||||
cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418
|
cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418
|
||||||
app3xx MACH_APP3XX APP3XX 1419
|
app3xx MACH_APP3XX APP3XX 1419
|
||||||
sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420
|
sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420
|
||||||
xscale_palmt700p MACH_XSCALE_PALMT700P XSCALE_PALMT700P 1421
|
palmtreo700p MACH_PALMTREO700P PALMTREO700P 1421
|
||||||
xscale_palmt700w MACH_XSCALE_PALMT700W XSCALE_PALMT700W 1422
|
palmtreo700w MACH_PALMTREO700W PALMTREO700W 1422
|
||||||
xscale_palmt750 MACH_XSCALE_PALMT750 XSCALE_PALMT750 1423
|
palmtreo750 MACH_PALMTREO750 PALMTREO750 1423
|
||||||
xscale_palmt755p MACH_XSCALE_PALMT755P XSCALE_PALMT755P 1424
|
palmtreo755p MACH_PALMTREO755P PALMTREO755P 1424
|
||||||
ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425
|
ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425
|
||||||
sarge MACH_SARGE SARGE 1426
|
sarge MACH_SARGE SARGE 1426
|
||||||
a696 MACH_A696 A696 1427
|
a696 MACH_A696 A696 1427
|
||||||
|
@ -1463,7 +1460,7 @@ artemis MACH_ARTEMIS ARTEMIS 1462
|
||||||
htctitan MACH_HTCTITAN HTCTITAN 1463
|
htctitan MACH_HTCTITAN HTCTITAN 1463
|
||||||
qranium MACH_QRANIUM QRANIUM 1464
|
qranium MACH_QRANIUM QRANIUM 1464
|
||||||
adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465
|
adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465
|
||||||
adx_medcom MACH_ADX_MEDINET ADX_MEDINET 1466
|
adx_medcom MACH_ADX_MEDCOM ADX_MEDCOM 1466
|
||||||
bboard MACH_BBOARD BBOARD 1467
|
bboard MACH_BBOARD BBOARD 1467
|
||||||
cambria MACH_CAMBRIA CAMBRIA 1468
|
cambria MACH_CAMBRIA CAMBRIA 1468
|
||||||
mt7xxx MACH_MT7XXX MT7XXX 1469
|
mt7xxx MACH_MT7XXX MT7XXX 1469
|
||||||
|
@ -1519,7 +1516,7 @@ wp188 MACH_WP188 WP188 1518
|
||||||
corsica MACH_CORSICA CORSICA 1519
|
corsica MACH_CORSICA CORSICA 1519
|
||||||
bigeye MACH_BIGEYE BIGEYE 1520
|
bigeye MACH_BIGEYE BIGEYE 1520
|
||||||
tll5000 MACH_TLL5000 TLL5000 1522
|
tll5000 MACH_TLL5000 TLL5000 1522
|
||||||
hni270 MACH_HNI_X270 HNI_X270 1523
|
bebot MACH_BEBOT BEBOT 1523
|
||||||
qong MACH_QONG QONG 1524
|
qong MACH_QONG QONG 1524
|
||||||
tcompact MACH_TCOMPACT TCOMPACT 1525
|
tcompact MACH_TCOMPACT TCOMPACT 1525
|
||||||
puma5 MACH_PUMA5 PUMA5 1526
|
puma5 MACH_PUMA5 PUMA5 1526
|
||||||
|
@ -1636,7 +1633,6 @@ awlug4lcu MACH_AWLUG4LCU AWLUG4LCU 1637
|
||||||
palermoc MACH_PALERMOC PALERMOC 1638
|
palermoc MACH_PALERMOC PALERMOC 1638
|
||||||
omap_ldp MACH_OMAP_LDP OMAP_LDP 1639
|
omap_ldp MACH_OMAP_LDP OMAP_LDP 1639
|
||||||
ip500 MACH_IP500 IP500 1640
|
ip500 MACH_IP500 IP500 1640
|
||||||
mx35ads MACH_MACH_MX35ADS MACH_MX35ADS 1641
|
|
||||||
ase2 MACH_ASE2 ASE2 1642
|
ase2 MACH_ASE2 ASE2 1642
|
||||||
mx35evb MACH_MX35EVB MX35EVB 1643
|
mx35evb MACH_MX35EVB MX35EVB 1643
|
||||||
aml_m8050 MACH_AML_M8050 AML_M8050 1644
|
aml_m8050 MACH_AML_M8050 AML_M8050 1644
|
||||||
|
@ -1647,7 +1643,7 @@ badger MACH_BADGER BADGER 1648
|
||||||
trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649
|
trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649
|
||||||
trizeps5 MACH_TRIZEPS5 TRIZEPS5 1650
|
trizeps5 MACH_TRIZEPS5 TRIZEPS5 1650
|
||||||
marlin MACH_MARLIN MARLIN 1651
|
marlin MACH_MARLIN MARLIN 1651
|
||||||
ts7800 MACH_TS7800 TS7800 1652
|
ts78xx MACH_TS78XX TS78XX 1652
|
||||||
hpipaq214 MACH_HPIPAQ214 HPIPAQ214 1653
|
hpipaq214 MACH_HPIPAQ214 HPIPAQ214 1653
|
||||||
at572d940dcm MACH_AT572D940DCM AT572D940DCM 1654
|
at572d940dcm MACH_AT572D940DCM AT572D940DCM 1654
|
||||||
ne1board MACH_NE1BOARD NE1BOARD 1655
|
ne1board MACH_NE1BOARD NE1BOARD 1655
|
||||||
|
@ -1720,3 +1716,99 @@ htc_kaiser MACH_HTC_KAISER HTC_KAISER 1724
|
||||||
lg_ks20 MACH_LG_KS20 LG_KS20 1725
|
lg_ks20 MACH_LG_KS20 LG_KS20 1725
|
||||||
hhgps MACH_HHGPS HHGPS 1726
|
hhgps MACH_HHGPS HHGPS 1726
|
||||||
nokia_n810_wimax MACH_NOKIA_N810_WIMAX NOKIA_N810_WIMAX 1727
|
nokia_n810_wimax MACH_NOKIA_N810_WIMAX NOKIA_N810_WIMAX 1727
|
||||||
|
insight MACH_INSIGHT INSIGHT 1728
|
||||||
|
sapphire MACH_SAPPHIRE SAPPHIRE 1729
|
||||||
|
csb637xo MACH_CSB637XO CSB637XO 1730
|
||||||
|
evisiong MACH_EVISIONG EVISIONG 1731
|
||||||
|
stmp37xx MACH_STMP37XX STMP37XX 1732
|
||||||
|
stmp378x MACH_STMP38XX STMP38XX 1733
|
||||||
|
tnt MACH_TNT TNT 1734
|
||||||
|
tbxt MACH_TBXT TBXT 1735
|
||||||
|
playmate MACH_PLAYMATE PLAYMATE 1736
|
||||||
|
pns10 MACH_PNS10 PNS10 1737
|
||||||
|
eznavi MACH_EZNAVI EZNAVI 1738
|
||||||
|
ps4000 MACH_PS4000 PS4000 1739
|
||||||
|
ezx_a780 MACH_EZX_A780 EZX_A780 1740
|
||||||
|
ezx_e680 MACH_EZX_E680 EZX_E680 1741
|
||||||
|
ezx_a1200 MACH_EZX_A1200 EZX_A1200 1742
|
||||||
|
ezx_e6 MACH_EZX_E6 EZX_E6 1743
|
||||||
|
ezx_e2 MACH_EZX_E2 EZX_E2 1744
|
||||||
|
ezx_a910 MACH_EZX_A910 EZX_A910 1745
|
||||||
|
cwmx31 MACH_CWMX31 CWMX31 1746
|
||||||
|
sl2312 MACH_SL2312 SL2312 1747
|
||||||
|
blenny MACH_BLENNY BLENNY 1748
|
||||||
|
ds107 MACH_DS107 DS107 1749
|
||||||
|
dsx07 MACH_DSX07 DSX07 1750
|
||||||
|
picocom1 MACH_PICOCOM1 PICOCOM1 1751
|
||||||
|
lynx_wolverine MACH_LYNX_WOLVERINE LYNX_WOLVERINE 1752
|
||||||
|
ubisys_p9_sc19 MACH_UBISYS_P9_SC19 UBISYS_P9_SC19 1753
|
||||||
|
kratos_low MACH_KRATOS_LOW KRATOS_LOW 1754
|
||||||
|
m700 MACH_M700 M700 1755
|
||||||
|
edmini_v2 MACH_EDMINI_V2 EDMINI_V2 1756
|
||||||
|
zipit2 MACH_ZIPIT2 ZIPIT2 1757
|
||||||
|
hslfemtocell MACH_HSLFEMTOCELL HSLFEMTOCELL 1758
|
||||||
|
daintree_at91 MACH_DAINTREE_AT91 DAINTREE_AT91 1759
|
||||||
|
sg560usb MACH_SG560USB SG560USB 1760
|
||||||
|
omap3_pandora MACH_OMAP3_PANDORA OMAP3_PANDORA 1761
|
||||||
|
usr8200 MACH_USR8200 USR8200 1762
|
||||||
|
s1s65k MACH_S1S65K S1S65K 1763
|
||||||
|
s2s65a MACH_S2S65A S2S65A 1764
|
||||||
|
icore MACH_ICORE ICORE 1765
|
||||||
|
mss2 MACH_MSS2 MSS2 1766
|
||||||
|
belmont MACH_BELMONT BELMONT 1767
|
||||||
|
asusp525 MACH_ASUSP525 ASUSP525 1768
|
||||||
|
lb88rc8480 MACH_LB88RC8480 LB88RC8480 1769
|
||||||
|
hipxa MACH_HIPXA HIPXA 1770
|
||||||
|
mx25_3ds MACH_MX25_3DS MX25_3DS 1771
|
||||||
|
m800 MACH_M800 M800 1772
|
||||||
|
omap3530_lv_som MACH_OMAP3530_LV_SOM OMAP3530_LV_SOM 1773
|
||||||
|
prima_evb MACH_PRIMA_EVB PRIMA_EVB 1774
|
||||||
|
mx31bt1 MACH_MX31BT1 MX31BT1 1775
|
||||||
|
atlas4_evb MACH_ATLAS4_EVB ATLAS4_EVB 1776
|
||||||
|
mx31cicada MACH_MX31CICADA MX31CICADA 1777
|
||||||
|
mi424wr MACH_MI424WR MI424WR 1778
|
||||||
|
axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779
|
||||||
|
at572d940deb MACH_AT572D940DEB AT572D940DEB 1780
|
||||||
|
davinci_da8xx_evm MACH_DAVINCI_DA8XX_EVM DAVINCI_DA8XX_EVM 1781
|
||||||
|
ep9302 MACH_EP9302 EP9302 1782
|
||||||
|
at572d940hfeb MACH_AT572D940HFEB AT572D940HFEB 1783
|
||||||
|
cybook3 MACH_CYBOOK3 CYBOOK3 1784
|
||||||
|
wdg002 MACH_WDG002 WDG002 1785
|
||||||
|
sg560adsl MACH_SG560ADSL SG560ADSL 1786
|
||||||
|
nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787
|
||||||
|
marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
|
||||||
|
vandihud MACH_VANDIHUD VANDIHUD 1790
|
||||||
|
magx_e8 MACH_MAGX_E8 MAGX_E8 1791
|
||||||
|
magx_z6 MACH_MAGX_Z6 MAGX_Z6 1792
|
||||||
|
magx_v8 MACH_MAGX_V8 MAGX_V8 1793
|
||||||
|
magx_u9 MACH_MAGX_U9 MAGX_U9 1794
|
||||||
|
toughcf08 MACH_TOUGHCF08 TOUGHCF08 1795
|
||||||
|
zw4400 MACH_ZW4400 ZW4400 1796
|
||||||
|
marat91 MACH_MARAT91 MARAT91 1797
|
||||||
|
overo MACH_OVERO OVERO 1798
|
||||||
|
at2440evb MACH_AT2440EVB AT2440EVB 1799
|
||||||
|
neocore926 MACH_NEOCORE926 NEOCORE926 1800
|
||||||
|
wnr854t MACH_WNR854T WNR854T 1801
|
||||||
|
imx27 MACH_IMX27 IMX27 1802
|
||||||
|
moose_db MACH_MOOSE_DB MOOSE_DB 1803
|
||||||
|
fab4 MACH_FAB4 FAB4 1804
|
||||||
|
htcdiamond MACH_HTCDIAMOND HTCDIAMOND 1805
|
||||||
|
fiona MACH_FIONA FIONA 1806
|
||||||
|
mxc30030_x MACH_MXC30030_X MXC30030_X 1807
|
||||||
|
bmp1000 MACH_BMP1000 BMP1000 1808
|
||||||
|
logi9200 MACH_LOGI9200 LOGI9200 1809
|
||||||
|
tqma31 MACH_TQMA31 TQMA31 1810
|
||||||
|
ccw9p9215js MACH_CCW9P9215JS CCW9P9215JS 1811
|
||||||
|
rd88f5181l_ge MACH_RD88F5181L_GE RD88F5181L_GE 1812
|
||||||
|
sifmain MACH_SIFMAIN SIFMAIN 1813
|
||||||
|
sam9_l9261 MACH_SAM9_L9261 SAM9_L9261 1814
|
||||||
|
cc9m2443js MACH_CC9M2443JS CC9M2443JS 1815
|
||||||
|
xaria300 MACH_XARIA300 XARIA300 1816
|
||||||
|
it9200 MACH_IT9200 IT9200 1817
|
||||||
|
rd88f5181l_fxo MACH_RD88F5181L_FXO RD88F5181L_FXO 1818
|
||||||
|
kriss_sensor MACH_KRISS_SENSOR KRISS_SENSOR 1819
|
||||||
|
pilz_pmi5 MACH_PILZ_PMI5 PILZ_PMI5 1820
|
||||||
|
jade MACH_JADE JADE 1821
|
||||||
|
ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822
|
||||||
|
gprisc4 MACH_GPRISC4 GPRISC4 1823
|
||||||
|
stamp9260 MACH_STAMP9260 STAMP9260 1824
|
||||||
|
|
|
@ -558,8 +558,6 @@ static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
|
||||||
if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
|
if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
|
||||||
rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
|
rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
|
||||||
NR_PREALLOCATE_RTE_ENTRIES);
|
NR_PREALLOCATE_RTE_ENTRIES);
|
||||||
if (!rte)
|
|
||||||
return NULL;
|
|
||||||
for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
|
for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
|
||||||
list_add(&rte->rte_list, &free_rte_list);
|
list_add(&rte->rte_list, &free_rte_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,8 +578,6 @@ setup_arch (char **cmdline_p)
|
||||||
cpu_init(); /* initialize the bootstrap CPU */
|
cpu_init(); /* initialize the bootstrap CPU */
|
||||||
mmu_context_init(); /* initialize context_id bitmap */
|
mmu_context_init(); /* initialize context_id bitmap */
|
||||||
|
|
||||||
check_sal_cache_flush();
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
acpi_boot_init();
|
acpi_boot_init();
|
||||||
#endif
|
#endif
|
||||||
|
@ -607,6 +605,7 @@ setup_arch (char **cmdline_p)
|
||||||
ia64_mca_init();
|
ia64_mca_init();
|
||||||
|
|
||||||
platform_setup(cmdline_p);
|
platform_setup(cmdline_p);
|
||||||
|
check_sal_cache_flush();
|
||||||
paging_init();
|
paging_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -512,6 +512,8 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si
|
||||||
int cpu;
|
int cpu;
|
||||||
char optstr[64];
|
char optstr[64];
|
||||||
|
|
||||||
|
if (count == 0 || count > sizeof(optstr))
|
||||||
|
return -EINVAL;
|
||||||
if (copy_from_user(optstr, user, count))
|
if (copy_from_user(optstr, user, count))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
optstr[count - 1] = '\0';
|
optstr[count - 1] = '\0';
|
||||||
|
|
|
@ -383,6 +383,7 @@ config VMI
|
||||||
config KVM_CLOCK
|
config KVM_CLOCK
|
||||||
bool "KVM paravirtualized clock"
|
bool "KVM paravirtualized clock"
|
||||||
select PARAVIRT
|
select PARAVIRT
|
||||||
|
select PARAVIRT_CLOCK
|
||||||
depends on !(X86_VISWS || X86_VOYAGER)
|
depends on !(X86_VISWS || X86_VOYAGER)
|
||||||
help
|
help
|
||||||
Turning on this option will allow you to run a paravirtualized clock
|
Turning on this option will allow you to run a paravirtualized clock
|
||||||
|
@ -410,6 +411,10 @@ config PARAVIRT
|
||||||
over full virtualization. However, when run without a hypervisor
|
over full virtualization. However, when run without a hypervisor
|
||||||
the kernel is theoretically slower and slightly larger.
|
the kernel is theoretically slower and slightly larger.
|
||||||
|
|
||||||
|
config PARAVIRT_CLOCK
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
config MEMTEST_BOOTPARAM
|
config MEMTEST_BOOTPARAM
|
||||||
|
|
|
@ -82,6 +82,7 @@ obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
|
||||||
obj-$(CONFIG_KVM_GUEST) += kvm.o
|
obj-$(CONFIG_KVM_GUEST) += kvm.o
|
||||||
obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
|
obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
|
||||||
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
|
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
|
||||||
|
obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
|
||||||
|
|
||||||
obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
|
obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/kvm_para.h>
|
#include <linux/kvm_para.h>
|
||||||
|
#include <asm/pvclock.h>
|
||||||
#include <asm/arch_hooks.h>
|
#include <asm/arch_hooks.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
|
@ -36,18 +37,9 @@ static int parse_no_kvmclock(char *arg)
|
||||||
early_param("no-kvmclock", parse_no_kvmclock);
|
early_param("no-kvmclock", parse_no_kvmclock);
|
||||||
|
|
||||||
/* The hypervisor will put information about time periodically here */
|
/* The hypervisor will put information about time periodically here */
|
||||||
static DEFINE_PER_CPU_SHARED_ALIGNED(struct kvm_vcpu_time_info, hv_clock);
|
static DEFINE_PER_CPU_SHARED_ALIGNED(struct pvclock_vcpu_time_info, hv_clock);
|
||||||
#define get_clock(cpu, field) per_cpu(hv_clock, cpu).field
|
static struct pvclock_wall_clock wall_clock;
|
||||||
|
|
||||||
static inline u64 kvm_get_delta(u64 last_tsc)
|
|
||||||
{
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
u64 delta = native_read_tsc() - last_tsc;
|
|
||||||
return (delta * get_clock(cpu, tsc_to_system_mul)) >> KVM_SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct kvm_wall_clock wall_clock;
|
|
||||||
static cycle_t kvm_clock_read(void);
|
|
||||||
/*
|
/*
|
||||||
* The wallclock is the time of day when we booted. Since then, some time may
|
* The wallclock is the time of day when we booted. Since then, some time may
|
||||||
* have elapsed since the hypervisor wrote the data. So we try to account for
|
* have elapsed since the hypervisor wrote the data. So we try to account for
|
||||||
|
@ -55,64 +47,37 @@ static cycle_t kvm_clock_read(void);
|
||||||
*/
|
*/
|
||||||
static unsigned long kvm_get_wallclock(void)
|
static unsigned long kvm_get_wallclock(void)
|
||||||
{
|
{
|
||||||
u32 wc_sec, wc_nsec;
|
struct pvclock_vcpu_time_info *vcpu_time;
|
||||||
u64 delta;
|
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
int version, nsec;
|
|
||||||
int low, high;
|
int low, high;
|
||||||
|
|
||||||
low = (int)__pa(&wall_clock);
|
low = (int)__pa(&wall_clock);
|
||||||
high = ((u64)__pa(&wall_clock) >> 32);
|
high = ((u64)__pa(&wall_clock) >> 32);
|
||||||
|
|
||||||
delta = kvm_clock_read();
|
|
||||||
|
|
||||||
native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
|
native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
|
||||||
do {
|
|
||||||
version = wall_clock.wc_version;
|
|
||||||
rmb();
|
|
||||||
wc_sec = wall_clock.wc_sec;
|
|
||||||
wc_nsec = wall_clock.wc_nsec;
|
|
||||||
rmb();
|
|
||||||
} while ((wall_clock.wc_version != version) || (version & 1));
|
|
||||||
|
|
||||||
delta = kvm_clock_read() - delta;
|
vcpu_time = &get_cpu_var(hv_clock);
|
||||||
delta += wc_nsec;
|
pvclock_read_wallclock(&wall_clock, vcpu_time, &ts);
|
||||||
nsec = do_div(delta, NSEC_PER_SEC);
|
put_cpu_var(hv_clock);
|
||||||
set_normalized_timespec(&ts, wc_sec + delta, nsec);
|
|
||||||
/*
|
return ts.tv_sec;
|
||||||
* Of all mechanisms of time adjustment I've tested, this one
|
|
||||||
* was the champion!
|
|
||||||
*/
|
|
||||||
return ts.tv_sec + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvm_set_wallclock(unsigned long now)
|
static int kvm_set_wallclock(unsigned long now)
|
||||||
{
|
{
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is our read_clock function. The host puts an tsc timestamp each time
|
|
||||||
* it updates a new time. Without the tsc adjustment, we can have a situation
|
|
||||||
* in which a vcpu starts to run earlier (smaller system_time), but probes
|
|
||||||
* time later (compared to another vcpu), leading to backwards time
|
|
||||||
*/
|
|
||||||
static cycle_t kvm_clock_read(void)
|
static cycle_t kvm_clock_read(void)
|
||||||
{
|
{
|
||||||
u64 last_tsc, now;
|
struct pvclock_vcpu_time_info *src;
|
||||||
int cpu;
|
cycle_t ret;
|
||||||
|
|
||||||
preempt_disable();
|
src = &get_cpu_var(hv_clock);
|
||||||
cpu = smp_processor_id();
|
ret = pvclock_clocksource_read(src);
|
||||||
|
put_cpu_var(hv_clock);
|
||||||
last_tsc = get_clock(cpu, tsc_timestamp);
|
return ret;
|
||||||
now = get_clock(cpu, system_time);
|
|
||||||
|
|
||||||
now += kvm_get_delta(last_tsc);
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clocksource kvm_clock = {
|
static struct clocksource kvm_clock = {
|
||||||
.name = "kvm-clock",
|
.name = "kvm-clock",
|
||||||
.read = kvm_clock_read,
|
.read = kvm_clock_read,
|
||||||
|
@ -123,13 +88,14 @@ static struct clocksource kvm_clock = {
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int kvm_register_clock(void)
|
static int kvm_register_clock(char *txt)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
int low, high;
|
int low, high;
|
||||||
low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1;
|
low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1;
|
||||||
high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32);
|
high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32);
|
||||||
|
printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n",
|
||||||
|
cpu, high, low, txt);
|
||||||
return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high);
|
return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,12 +106,20 @@ static void kvm_setup_secondary_clock(void)
|
||||||
* Now that the first cpu already had this clocksource initialized,
|
* Now that the first cpu already had this clocksource initialized,
|
||||||
* we shouldn't fail.
|
* we shouldn't fail.
|
||||||
*/
|
*/
|
||||||
WARN_ON(kvm_register_clock());
|
WARN_ON(kvm_register_clock("secondary cpu clock"));
|
||||||
/* ok, done with our trickery, call native */
|
/* ok, done with our trickery, call native */
|
||||||
setup_secondary_APIC_clock();
|
setup_secondary_APIC_clock();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
void __init kvm_smp_prepare_boot_cpu(void)
|
||||||
|
{
|
||||||
|
WARN_ON(kvm_register_clock("primary cpu clock"));
|
||||||
|
native_smp_prepare_boot_cpu();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* After the clock is registered, the host will keep writing to the
|
* After the clock is registered, the host will keep writing to the
|
||||||
* registered memory location. If the guest happens to shutdown, this memory
|
* registered memory location. If the guest happens to shutdown, this memory
|
||||||
|
@ -174,13 +148,16 @@ void __init kvmclock_init(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
|
if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
|
||||||
if (kvm_register_clock())
|
if (kvm_register_clock("boot clock"))
|
||||||
return;
|
return;
|
||||||
pv_time_ops.get_wallclock = kvm_get_wallclock;
|
pv_time_ops.get_wallclock = kvm_get_wallclock;
|
||||||
pv_time_ops.set_wallclock = kvm_set_wallclock;
|
pv_time_ops.set_wallclock = kvm_set_wallclock;
|
||||||
pv_time_ops.sched_clock = kvm_clock_read;
|
pv_time_ops.sched_clock = kvm_clock_read;
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
|
pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
|
||||||
#endif
|
#endif
|
||||||
machine_ops.shutdown = kvm_shutdown;
|
machine_ops.shutdown = kvm_shutdown;
|
||||||
#ifdef CONFIG_KEXEC
|
#ifdef CONFIG_KEXEC
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* paravirtual clock -- common code used by kvm/xen
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/percpu.h>
|
||||||
|
#include <asm/pvclock.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are perodically updated
|
||||||
|
* xen: magic shared_info page
|
||||||
|
* kvm: gpa registered via msr
|
||||||
|
* and then copied here.
|
||||||
|
*/
|
||||||
|
struct pvclock_shadow_time {
|
||||||
|
u64 tsc_timestamp; /* TSC at last update of time vals. */
|
||||||
|
u64 system_timestamp; /* Time, in nanosecs, since boot. */
|
||||||
|
u32 tsc_to_nsec_mul;
|
||||||
|
int tsc_shift;
|
||||||
|
u32 version;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
|
||||||
|
* yielding a 64-bit result.
|
||||||
|
*/
|
||||||
|
static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
|
||||||
|
{
|
||||||
|
u64 product;
|
||||||
|
#ifdef __i386__
|
||||||
|
u32 tmp1, tmp2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (shift < 0)
|
||||||
|
delta >>= -shift;
|
||||||
|
else
|
||||||
|
delta <<= shift;
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
__asm__ (
|
||||||
|
"mul %5 ; "
|
||||||
|
"mov %4,%%eax ; "
|
||||||
|
"mov %%edx,%4 ; "
|
||||||
|
"mul %5 ; "
|
||||||
|
"xor %5,%5 ; "
|
||||||
|
"add %4,%%eax ; "
|
||||||
|
"adc %5,%%edx ; "
|
||||||
|
: "=A" (product), "=r" (tmp1), "=r" (tmp2)
|
||||||
|
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
|
||||||
|
#elif __x86_64__
|
||||||
|
__asm__ (
|
||||||
|
"mul %%rdx ; shrd $32,%%rdx,%%rax"
|
||||||
|
: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
|
||||||
|
#else
|
||||||
|
#error implement me!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow)
|
||||||
|
{
|
||||||
|
u64 delta = native_read_tsc() - shadow->tsc_timestamp;
|
||||||
|
return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reads a consistent set of time-base values from hypervisor,
|
||||||
|
* into a shadow data area.
|
||||||
|
*/
|
||||||
|
static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst,
|
||||||
|
struct pvclock_vcpu_time_info *src)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
dst->version = src->version;
|
||||||
|
rmb(); /* fetch version before data */
|
||||||
|
dst->tsc_timestamp = src->tsc_timestamp;
|
||||||
|
dst->system_timestamp = src->system_time;
|
||||||
|
dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
|
||||||
|
dst->tsc_shift = src->tsc_shift;
|
||||||
|
rmb(); /* test version after fetching data */
|
||||||
|
} while ((src->version & 1) || (dst->version != src->version));
|
||||||
|
|
||||||
|
return dst->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
|
||||||
|
{
|
||||||
|
struct pvclock_shadow_time shadow;
|
||||||
|
unsigned version;
|
||||||
|
cycle_t ret, offset;
|
||||||
|
|
||||||
|
do {
|
||||||
|
version = pvclock_get_time_values(&shadow, src);
|
||||||
|
barrier();
|
||||||
|
offset = pvclock_get_nsec_offset(&shadow);
|
||||||
|
ret = shadow.system_timestamp + offset;
|
||||||
|
barrier();
|
||||||
|
} while (version != src->version);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
|
||||||
|
struct pvclock_vcpu_time_info *vcpu_time,
|
||||||
|
struct timespec *ts)
|
||||||
|
{
|
||||||
|
u32 version;
|
||||||
|
u64 delta;
|
||||||
|
struct timespec now;
|
||||||
|
|
||||||
|
/* get wallclock at system boot */
|
||||||
|
do {
|
||||||
|
version = wall_clock->version;
|
||||||
|
rmb(); /* fetch version before time */
|
||||||
|
now.tv_sec = wall_clock->sec;
|
||||||
|
now.tv_nsec = wall_clock->nsec;
|
||||||
|
rmb(); /* fetch time before checking version */
|
||||||
|
} while ((wall_clock->version & 1) || (version != wall_clock->version));
|
||||||
|
|
||||||
|
delta = pvclock_clocksource_read(vcpu_time); /* time since system boot */
|
||||||
|
delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec;
|
||||||
|
|
||||||
|
now.tv_nsec = do_div(delta, NSEC_PER_SEC);
|
||||||
|
now.tv_sec = delta;
|
||||||
|
|
||||||
|
set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
|
||||||
|
}
|
|
@ -200,9 +200,12 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)
|
||||||
|
|
||||||
atomic_inc(&pt->pending);
|
atomic_inc(&pt->pending);
|
||||||
smp_mb__after_atomic_inc();
|
smp_mb__after_atomic_inc();
|
||||||
if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
|
if (vcpu0) {
|
||||||
vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
|
set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
|
||||||
wake_up_interruptible(&vcpu0->wq);
|
if (waitqueue_active(&vcpu0->wq)) {
|
||||||
|
vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
|
||||||
|
wake_up_interruptible(&vcpu0->wq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
|
pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
|
||||||
|
|
|
@ -940,6 +940,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
|
||||||
wait_queue_head_t *q = &apic->vcpu->wq;
|
wait_queue_head_t *q = &apic->vcpu->wq;
|
||||||
|
|
||||||
atomic_inc(&apic->timer.pending);
|
atomic_inc(&apic->timer.pending);
|
||||||
|
set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
|
||||||
if (waitqueue_active(q)) {
|
if (waitqueue_active(q)) {
|
||||||
apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
|
apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
|
||||||
wake_up_interruptible(q);
|
wake_up_interruptible(q);
|
||||||
|
|
|
@ -640,6 +640,7 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn)
|
||||||
rmap_remove(kvm, spte);
|
rmap_remove(kvm, spte);
|
||||||
--kvm->stat.lpages;
|
--kvm->stat.lpages;
|
||||||
set_shadow_pte(spte, shadow_trap_nonpresent_pte);
|
set_shadow_pte(spte, shadow_trap_nonpresent_pte);
|
||||||
|
spte = NULL;
|
||||||
write_protected = 1;
|
write_protected = 1;
|
||||||
}
|
}
|
||||||
spte = rmap_next(kvm, rmapp, spte);
|
spte = rmap_next(kvm, rmapp, spte);
|
||||||
|
@ -1082,10 +1083,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
|
||||||
struct kvm_mmu_page *shadow;
|
struct kvm_mmu_page *shadow;
|
||||||
|
|
||||||
spte |= PT_WRITABLE_MASK;
|
spte |= PT_WRITABLE_MASK;
|
||||||
if (user_fault) {
|
|
||||||
mmu_unshadow(vcpu->kvm, gfn);
|
|
||||||
goto unshadowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
|
shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
|
||||||
if (shadow ||
|
if (shadow ||
|
||||||
|
@ -1102,8 +1099,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unshadowed:
|
|
||||||
|
|
||||||
if (pte_access & ACC_WRITE_MASK)
|
if (pte_access & ACC_WRITE_MASK)
|
||||||
mark_page_dirty(vcpu->kvm, gfn);
|
mark_page_dirty(vcpu->kvm, gfn);
|
||||||
|
|
||||||
|
@ -1580,11 +1575,13 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
|
||||||
u64 *spte,
|
u64 *spte,
|
||||||
const void *new)
|
const void *new)
|
||||||
{
|
{
|
||||||
if ((sp->role.level != PT_PAGE_TABLE_LEVEL)
|
if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
|
||||||
&& !vcpu->arch.update_pte.largepage) {
|
if (!vcpu->arch.update_pte.largepage ||
|
||||||
++vcpu->kvm->stat.mmu_pde_zapped;
|
sp->role.glevels == PT32_ROOT_LEVEL) {
|
||||||
return;
|
++vcpu->kvm->stat.mmu_pde_zapped;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++vcpu->kvm->stat.mmu_pte_updated;
|
++vcpu->kvm->stat.mmu_pte_updated;
|
||||||
if (sp->role.glevels == PT32_ROOT_LEVEL)
|
if (sp->role.glevels == PT32_ROOT_LEVEL)
|
||||||
|
|
|
@ -566,7 +566,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
||||||
load_transition_efer(vmx);
|
load_transition_efer(vmx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmx_load_host_state(struct vcpu_vmx *vmx)
|
static void __vmx_load_host_state(struct vcpu_vmx *vmx)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -596,6 +596,13 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
|
||||||
reload_host_efer(vmx);
|
reload_host_efer(vmx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vmx_load_host_state(struct vcpu_vmx *vmx)
|
||||||
|
{
|
||||||
|
preempt_disable();
|
||||||
|
__vmx_load_host_state(vmx);
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
|
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
|
||||||
* vcpu mutex is already taken.
|
* vcpu mutex is already taken.
|
||||||
|
@ -654,7 +661,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||||
|
|
||||||
static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
|
static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
vmx_load_host_state(to_vmx(vcpu));
|
__vmx_load_host_state(to_vmx(vcpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
|
static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
|
||||||
|
@ -884,11 +891,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
|
||||||
switch (msr_index) {
|
switch (msr_index) {
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
case MSR_EFER:
|
case MSR_EFER:
|
||||||
|
vmx_load_host_state(vmx);
|
||||||
ret = kvm_set_msr_common(vcpu, msr_index, data);
|
ret = kvm_set_msr_common(vcpu, msr_index, data);
|
||||||
if (vmx->host_state.loaded) {
|
|
||||||
reload_host_efer(vmx);
|
|
||||||
load_transition_efer(vmx);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MSR_FS_BASE:
|
case MSR_FS_BASE:
|
||||||
vmcs_writel(GUEST_FS_BASE, data);
|
vmcs_writel(GUEST_FS_BASE, data);
|
||||||
|
@ -910,11 +914,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
|
||||||
guest_write_tsc(data);
|
guest_write_tsc(data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
vmx_load_host_state(vmx);
|
||||||
msr = find_msr_entry(vmx, msr_index);
|
msr = find_msr_entry(vmx, msr_index);
|
||||||
if (msr) {
|
if (msr) {
|
||||||
msr->data = data;
|
msr->data = data;
|
||||||
if (vmx->host_state.loaded)
|
|
||||||
load_msrs(vmx->guest_msrs, vmx->save_nmsrs);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = kvm_set_msr_common(vcpu, msr_index, data);
|
ret = kvm_set_msr_common(vcpu, msr_index, data);
|
||||||
|
|
|
@ -492,8 +492,8 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
|
||||||
static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
|
static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
|
||||||
{
|
{
|
||||||
static int version;
|
static int version;
|
||||||
struct kvm_wall_clock wc;
|
struct pvclock_wall_clock wc;
|
||||||
struct timespec wc_ts;
|
struct timespec now, sys, boot;
|
||||||
|
|
||||||
if (!wall_clock)
|
if (!wall_clock)
|
||||||
return;
|
return;
|
||||||
|
@ -502,10 +502,19 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
|
||||||
|
|
||||||
kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
|
kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
|
||||||
|
|
||||||
wc_ts = current_kernel_time();
|
/*
|
||||||
wc.wc_sec = wc_ts.tv_sec;
|
* The guest calculates current wall clock time by adding
|
||||||
wc.wc_nsec = wc_ts.tv_nsec;
|
* system time (updated by kvm_write_guest_time below) to the
|
||||||
wc.wc_version = version;
|
* wall clock specified here. guest system time equals host
|
||||||
|
* system time for us, thus we must fill in host boot time here.
|
||||||
|
*/
|
||||||
|
now = current_kernel_time();
|
||||||
|
ktime_get_ts(&sys);
|
||||||
|
boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys));
|
||||||
|
|
||||||
|
wc.sec = boot.tv_sec;
|
||||||
|
wc.nsec = boot.tv_nsec;
|
||||||
|
wc.version = version;
|
||||||
|
|
||||||
kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
|
kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
|
||||||
|
|
||||||
|
@ -513,6 +522,45 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
|
||||||
kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
|
kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
|
||||||
|
{
|
||||||
|
uint32_t quotient, remainder;
|
||||||
|
|
||||||
|
/* Don't try to replace with do_div(), this one calculates
|
||||||
|
* "(dividend << 32) / divisor" */
|
||||||
|
__asm__ ( "divl %4"
|
||||||
|
: "=a" (quotient), "=d" (remainder)
|
||||||
|
: "0" (0), "1" (dividend), "r" (divisor) );
|
||||||
|
return quotient;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *hv_clock)
|
||||||
|
{
|
||||||
|
uint64_t nsecs = 1000000000LL;
|
||||||
|
int32_t shift = 0;
|
||||||
|
uint64_t tps64;
|
||||||
|
uint32_t tps32;
|
||||||
|
|
||||||
|
tps64 = tsc_khz * 1000LL;
|
||||||
|
while (tps64 > nsecs*2) {
|
||||||
|
tps64 >>= 1;
|
||||||
|
shift--;
|
||||||
|
}
|
||||||
|
|
||||||
|
tps32 = (uint32_t)tps64;
|
||||||
|
while (tps32 <= (uint32_t)nsecs) {
|
||||||
|
tps32 <<= 1;
|
||||||
|
shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
hv_clock->tsc_shift = shift;
|
||||||
|
hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
|
||||||
|
|
||||||
|
pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
|
||||||
|
__FUNCTION__, tsc_khz, hv_clock->tsc_shift,
|
||||||
|
hv_clock->tsc_to_system_mul);
|
||||||
|
}
|
||||||
|
|
||||||
static void kvm_write_guest_time(struct kvm_vcpu *v)
|
static void kvm_write_guest_time(struct kvm_vcpu *v)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
@ -523,6 +571,11 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
|
||||||
if ((!vcpu->time_page))
|
if ((!vcpu->time_page))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) {
|
||||||
|
kvm_set_time_scale(tsc_khz, &vcpu->hv_clock);
|
||||||
|
vcpu->hv_clock_tsc_khz = tsc_khz;
|
||||||
|
}
|
||||||
|
|
||||||
/* Keep irq disabled to prevent changes to the clock */
|
/* Keep irq disabled to prevent changes to the clock */
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER,
|
kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER,
|
||||||
|
@ -537,14 +590,14 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
|
||||||
/*
|
/*
|
||||||
* The interface expects us to write an even number signaling that the
|
* The interface expects us to write an even number signaling that the
|
||||||
* update is finished. Since the guest won't see the intermediate
|
* update is finished. Since the guest won't see the intermediate
|
||||||
* state, we just write "2" at the end
|
* state, we just increase by 2 at the end.
|
||||||
*/
|
*/
|
||||||
vcpu->hv_clock.version = 2;
|
vcpu->hv_clock.version += 2;
|
||||||
|
|
||||||
shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
|
shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
|
||||||
|
|
||||||
memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
|
memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
|
||||||
sizeof(vcpu->hv_clock));
|
sizeof(vcpu->hv_clock));
|
||||||
|
|
||||||
kunmap_atomic(shared_kaddr, KM_USER0);
|
kunmap_atomic(shared_kaddr, KM_USER0);
|
||||||
|
|
||||||
|
@ -599,10 +652,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
||||||
/* ...but clean it before doing the actual write */
|
/* ...but clean it before doing the actual write */
|
||||||
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
|
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
|
||||||
|
|
||||||
vcpu->arch.hv_clock.tsc_to_system_mul =
|
|
||||||
clocksource_khz2mult(tsc_khz, 22);
|
|
||||||
vcpu->arch.hv_clock.tsc_shift = 22;
|
|
||||||
|
|
||||||
down_read(¤t->mm->mmap_sem);
|
down_read(¤t->mm->mmap_sem);
|
||||||
vcpu->arch.time_page =
|
vcpu->arch.time_page =
|
||||||
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
|
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
|
||||||
|
@ -2759,6 +2808,8 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
if (vcpu->requests) {
|
if (vcpu->requests) {
|
||||||
if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
|
if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
|
||||||
__kvm_migrate_timers(vcpu);
|
__kvm_migrate_timers(vcpu);
|
||||||
|
if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
|
||||||
|
kvm_x86_ops->tlb_flush(vcpu);
|
||||||
if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
|
if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
|
||||||
&vcpu->requests)) {
|
&vcpu->requests)) {
|
||||||
kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
|
kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
|
||||||
|
@ -2772,6 +2823,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
|
||||||
kvm_inject_pending_timer_irqs(vcpu);
|
kvm_inject_pending_timer_irqs(vcpu);
|
||||||
|
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
@ -2781,21 +2833,13 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
|
|
||||||
if (need_resched()) {
|
if (vcpu->requests || need_resched()) {
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vcpu->requests)
|
|
||||||
if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) {
|
|
||||||
local_irq_enable();
|
|
||||||
preempt_enable();
|
|
||||||
r = 1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
|
@ -2825,9 +2869,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
|
|
||||||
kvm_guest_enter();
|
kvm_guest_enter();
|
||||||
|
|
||||||
if (vcpu->requests)
|
|
||||||
if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
|
|
||||||
kvm_x86_ops->tlb_flush(vcpu);
|
|
||||||
|
|
||||||
KVMTRACE_0D(VMENTRY, vcpu, entryexit);
|
KVMTRACE_0D(VMENTRY, vcpu, entryexit);
|
||||||
kvm_x86_ops->run(vcpu, kvm_run);
|
kvm_x86_ops->run(vcpu, kvm_run);
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
config XEN
|
config XEN
|
||||||
bool "Xen guest support"
|
bool "Xen guest support"
|
||||||
select PARAVIRT
|
select PARAVIRT
|
||||||
|
select PARAVIRT_CLOCK
|
||||||
depends on X86_32
|
depends on X86_32
|
||||||
depends on X86_CMPXCHG && X86_TSC && !(X86_VISWS || X86_VOYAGER)
|
depends on X86_CMPXCHG && X86_TSC && X86_PAE && !(X86_VISWS || X86_VOYAGER)
|
||||||
help
|
help
|
||||||
This is the Linux Xen port. Enabling this will allow the
|
This is the Linux Xen port. Enabling this will allow the
|
||||||
kernel to boot in a paravirtualized environment under the
|
kernel to boot in a paravirtualized environment under the
|
||||||
|
|
|
@ -785,38 +785,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
|
||||||
static __init void xen_pagetable_setup_start(pgd_t *base)
|
static __init void xen_pagetable_setup_start(pgd_t *base)
|
||||||
{
|
{
|
||||||
pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
|
pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* special set_pte for pagetable initialization */
|
/* special set_pte for pagetable initialization */
|
||||||
pv_mmu_ops.set_pte = xen_set_pte_init;
|
pv_mmu_ops.set_pte = xen_set_pte_init;
|
||||||
|
|
||||||
init_mm.pgd = base;
|
init_mm.pgd = base;
|
||||||
/*
|
/*
|
||||||
* copy top-level of Xen-supplied pagetable into place. For
|
* copy top-level of Xen-supplied pagetable into place. This
|
||||||
* !PAE we can use this as-is, but for PAE it is a stand-in
|
* is a stand-in while we copy the pmd pages.
|
||||||
* while we copy the pmd pages.
|
|
||||||
*/
|
*/
|
||||||
memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
|
memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
|
||||||
|
|
||||||
if (PTRS_PER_PMD > 1) {
|
/*
|
||||||
int i;
|
* For PAE, need to allocate new pmds, rather than
|
||||||
/*
|
* share Xen's, since Xen doesn't like pmd's being
|
||||||
* For PAE, need to allocate new pmds, rather than
|
* shared between address spaces.
|
||||||
* share Xen's, since Xen doesn't like pmd's being
|
*/
|
||||||
* shared between address spaces.
|
for (i = 0; i < PTRS_PER_PGD; i++) {
|
||||||
*/
|
if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
|
||||||
for (i = 0; i < PTRS_PER_PGD; i++) {
|
pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
|
||||||
if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
|
|
||||||
pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
|
|
||||||
|
|
||||||
memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
|
memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
|
|
||||||
make_lowmem_page_readonly(pmd);
|
make_lowmem_page_readonly(pmd);
|
||||||
|
|
||||||
set_pgd(&base[i], __pgd(1 + __pa(pmd)));
|
set_pgd(&base[i], __pgd(1 + __pa(pmd)));
|
||||||
} else
|
} else
|
||||||
pgd_clear(&base[i]);
|
pgd_clear(&base[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure zero_page is mapped RO so we can use it in pagetables */
|
/* make sure zero_page is mapped RO so we can use it in pagetables */
|
||||||
|
@ -873,17 +870,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
|
||||||
|
|
||||||
/* Actually pin the pagetable down, but we can't set PG_pinned
|
/* Actually pin the pagetable down, but we can't set PG_pinned
|
||||||
yet because the page structures don't exist yet. */
|
yet because the page structures don't exist yet. */
|
||||||
{
|
pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
|
||||||
unsigned level;
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
level = MMUEXT_PIN_L3_TABLE;
|
|
||||||
#else
|
|
||||||
level = MMUEXT_PIN_L2_TABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called once we have the cpu_possible_map */
|
/* This is called once we have the cpu_possible_map */
|
||||||
|
@ -1093,7 +1080,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||||
.make_pte = xen_make_pte,
|
.make_pte = xen_make_pte,
|
||||||
.make_pgd = xen_make_pgd,
|
.make_pgd = xen_make_pgd,
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
.set_pte_atomic = xen_set_pte_atomic,
|
.set_pte_atomic = xen_set_pte_atomic,
|
||||||
.set_pte_present = xen_set_pte_at,
|
.set_pte_present = xen_set_pte_at,
|
||||||
.set_pud = xen_set_pud,
|
.set_pud = xen_set_pud,
|
||||||
|
@ -1102,7 +1088,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||||
|
|
||||||
.make_pmd = xen_make_pmd,
|
.make_pmd = xen_make_pmd,
|
||||||
.pmd_val = xen_pmd_val,
|
.pmd_val = xen_pmd_val,
|
||||||
#endif /* PAE */
|
|
||||||
|
|
||||||
.activate_mm = xen_activate_mm,
|
.activate_mm = xen_activate_mm,
|
||||||
.dup_mmap = xen_dup_mmap,
|
.dup_mmap = xen_dup_mmap,
|
||||||
|
@ -1228,6 +1213,11 @@ asmlinkage void __init xen_start_kernel(void)
|
||||||
if (xen_feature(XENFEAT_supervisor_mode_kernel))
|
if (xen_feature(XENFEAT_supervisor_mode_kernel))
|
||||||
pv_info.kernel_rpl = 0;
|
pv_info.kernel_rpl = 0;
|
||||||
|
|
||||||
|
/* Prevent unwanted bits from being set in PTEs. */
|
||||||
|
__supported_pte_mask &= ~_PAGE_GLOBAL;
|
||||||
|
if (!is_initial_xendomain())
|
||||||
|
__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
|
||||||
|
|
||||||
/* set the limit of our address space */
|
/* set the limit of our address space */
|
||||||
xen_reserve_top();
|
xen_reserve_top();
|
||||||
|
|
||||||
|
|
|
@ -179,50 +179,56 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assume pteval_t is equivalent to all the other *val_t types. */
|
||||||
|
static pteval_t pte_mfn_to_pfn(pteval_t val)
|
||||||
|
{
|
||||||
|
if (val & _PAGE_PRESENT) {
|
||||||
|
unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT;
|
||||||
|
pteval_t flags = val & ~PTE_MASK;
|
||||||
|
val = (mfn_to_pfn(mfn) << PAGE_SHIFT) | flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pteval_t pte_pfn_to_mfn(pteval_t val)
|
||||||
|
{
|
||||||
|
if (val & _PAGE_PRESENT) {
|
||||||
|
unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT;
|
||||||
|
pteval_t flags = val & ~PTE_MASK;
|
||||||
|
val = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
pteval_t xen_pte_val(pte_t pte)
|
pteval_t xen_pte_val(pte_t pte)
|
||||||
{
|
{
|
||||||
pteval_t ret = pte.pte;
|
return pte_mfn_to_pfn(pte.pte);
|
||||||
|
|
||||||
if (ret & _PAGE_PRESENT)
|
|
||||||
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pgdval_t xen_pgd_val(pgd_t pgd)
|
pgdval_t xen_pgd_val(pgd_t pgd)
|
||||||
{
|
{
|
||||||
pgdval_t ret = pgd.pgd;
|
return pte_mfn_to_pfn(pgd.pgd);
|
||||||
if (ret & _PAGE_PRESENT)
|
|
||||||
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pte_t xen_make_pte(pteval_t pte)
|
pte_t xen_make_pte(pteval_t pte)
|
||||||
{
|
{
|
||||||
if (pte & _PAGE_PRESENT) {
|
pte = pte_pfn_to_mfn(pte);
|
||||||
pte = phys_to_machine(XPADDR(pte)).maddr;
|
return native_make_pte(pte);
|
||||||
pte &= ~(_PAGE_PCD | _PAGE_PWT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (pte_t){ .pte = pte };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pgd_t xen_make_pgd(pgdval_t pgd)
|
pgd_t xen_make_pgd(pgdval_t pgd)
|
||||||
{
|
{
|
||||||
if (pgd & _PAGE_PRESENT)
|
pgd = pte_pfn_to_mfn(pgd);
|
||||||
pgd = phys_to_machine(XPADDR(pgd)).maddr;
|
return native_make_pgd(pgd);
|
||||||
|
|
||||||
return (pgd_t){ pgd };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pmdval_t xen_pmd_val(pmd_t pmd)
|
pmdval_t xen_pmd_val(pmd_t pmd)
|
||||||
{
|
{
|
||||||
pmdval_t ret = native_pmd_val(pmd);
|
return pte_mfn_to_pfn(pmd.pmd);
|
||||||
if (ret & _PAGE_PRESENT)
|
|
||||||
ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
void xen_set_pud(pud_t *ptr, pud_t val)
|
void xen_set_pud(pud_t *ptr, pud_t val)
|
||||||
{
|
{
|
||||||
struct multicall_space mcs;
|
struct multicall_space mcs;
|
||||||
|
@ -267,17 +273,9 @@ void xen_pmd_clear(pmd_t *pmdp)
|
||||||
|
|
||||||
pmd_t xen_make_pmd(pmdval_t pmd)
|
pmd_t xen_make_pmd(pmdval_t pmd)
|
||||||
{
|
{
|
||||||
if (pmd & _PAGE_PRESENT)
|
pmd = pte_pfn_to_mfn(pmd);
|
||||||
pmd = phys_to_machine(XPADDR(pmd)).maddr;
|
|
||||||
|
|
||||||
return native_make_pmd(pmd);
|
return native_make_pmd(pmd);
|
||||||
}
|
}
|
||||||
#else /* !PAE */
|
|
||||||
void xen_set_pte(pte_t *ptep, pte_t pte)
|
|
||||||
{
|
|
||||||
*ptep = pte;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_X86_PAE */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(Yet another) pagetable walker. This one is intended for pinning a
|
(Yet another) pagetable walker. This one is intended for pinning a
|
||||||
|
@ -430,8 +428,6 @@ static int pin_page(struct page *page, enum pt_level level)
|
||||||
read-only, and can be pinned. */
|
read-only, and can be pinned. */
|
||||||
void xen_pgd_pin(pgd_t *pgd)
|
void xen_pgd_pin(pgd_t *pgd)
|
||||||
{
|
{
|
||||||
unsigned level;
|
|
||||||
|
|
||||||
xen_mc_batch();
|
xen_mc_batch();
|
||||||
|
|
||||||
if (pgd_walk(pgd, pin_page, TASK_SIZE)) {
|
if (pgd_walk(pgd, pin_page, TASK_SIZE)) {
|
||||||
|
@ -441,14 +437,7 @@ void xen_pgd_pin(pgd_t *pgd)
|
||||||
xen_mc_batch();
|
xen_mc_batch();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));
|
||||||
level = MMUEXT_PIN_L3_TABLE;
|
|
||||||
#else
|
|
||||||
level = MMUEXT_PIN_L2_TABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xen_do_pin(level, PFN_DOWN(__pa(pgd)));
|
|
||||||
|
|
||||||
xen_mc_issue(0);
|
xen_mc_issue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,13 @@ void xen_exit_mmap(struct mm_struct *mm);
|
||||||
void xen_pgd_pin(pgd_t *pgd);
|
void xen_pgd_pin(pgd_t *pgd);
|
||||||
//void xen_pgd_unpin(pgd_t *pgd);
|
//void xen_pgd_unpin(pgd_t *pgd);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
pteval_t xen_pte_val(pte_t);
|
||||||
unsigned long long xen_pte_val(pte_t);
|
pmdval_t xen_pmd_val(pmd_t);
|
||||||
unsigned long long xen_pmd_val(pmd_t);
|
pgdval_t xen_pgd_val(pgd_t);
|
||||||
unsigned long long xen_pgd_val(pgd_t);
|
|
||||||
|
|
||||||
pte_t xen_make_pte(unsigned long long);
|
pte_t xen_make_pte(pteval_t);
|
||||||
pmd_t xen_make_pmd(unsigned long long);
|
pmd_t xen_make_pmd(pmdval_t);
|
||||||
pgd_t xen_make_pgd(unsigned long long);
|
pgd_t xen_make_pgd(pgdval_t);
|
||||||
|
|
||||||
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
|
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||||
pte_t *ptep, pte_t pteval);
|
pte_t *ptep, pte_t pteval);
|
||||||
|
@ -53,15 +52,4 @@ void xen_set_pud(pud_t *ptr, pud_t val);
|
||||||
void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
||||||
void xen_pmd_clear(pmd_t *pmdp);
|
void xen_pmd_clear(pmd_t *pmdp);
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
unsigned long xen_pte_val(pte_t);
|
|
||||||
unsigned long xen_pmd_val(pmd_t);
|
|
||||||
unsigned long xen_pgd_val(pgd_t);
|
|
||||||
|
|
||||||
pte_t xen_make_pte(unsigned long);
|
|
||||||
pmd_t xen_make_pmd(unsigned long);
|
|
||||||
pgd_t xen_make_pgd(unsigned long);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _XEN_MMU_H */
|
#endif /* _XEN_MMU_H */
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
|
|
||||||
|
#include <asm/pvclock.h>
|
||||||
#include <asm/xen/hypervisor.h>
|
#include <asm/xen/hypervisor.h>
|
||||||
#include <asm/xen/hypercall.h>
|
#include <asm/xen/hypercall.h>
|
||||||
|
|
||||||
|
@ -31,17 +32,6 @@
|
||||||
|
|
||||||
static cycle_t xen_clocksource_read(void);
|
static cycle_t xen_clocksource_read(void);
|
||||||
|
|
||||||
/* These are perodically updated in shared_info, and then copied here. */
|
|
||||||
struct shadow_time_info {
|
|
||||||
u64 tsc_timestamp; /* TSC at last update of time vals. */
|
|
||||||
u64 system_timestamp; /* Time, in nanosecs, since boot. */
|
|
||||||
u32 tsc_to_nsec_mul;
|
|
||||||
int tsc_shift;
|
|
||||||
u32 version;
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct shadow_time_info, shadow_time);
|
|
||||||
|
|
||||||
/* runstate info updated by Xen */
|
/* runstate info updated by Xen */
|
||||||
static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
|
static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
|
||||||
|
|
||||||
|
@ -211,7 +201,7 @@ unsigned long long xen_sched_clock(void)
|
||||||
unsigned long xen_cpu_khz(void)
|
unsigned long xen_cpu_khz(void)
|
||||||
{
|
{
|
||||||
u64 xen_khz = 1000000ULL << 32;
|
u64 xen_khz = 1000000ULL << 32;
|
||||||
const struct vcpu_time_info *info =
|
const struct pvclock_vcpu_time_info *info =
|
||||||
&HYPERVISOR_shared_info->vcpu_info[0].time;
|
&HYPERVISOR_shared_info->vcpu_info[0].time;
|
||||||
|
|
||||||
do_div(xen_khz, info->tsc_to_system_mul);
|
do_div(xen_khz, info->tsc_to_system_mul);
|
||||||
|
@ -223,121 +213,26 @@ unsigned long xen_cpu_khz(void)
|
||||||
return xen_khz;
|
return xen_khz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Reads a consistent set of time-base values from Xen, into a shadow data
|
|
||||||
* area.
|
|
||||||
*/
|
|
||||||
static unsigned get_time_values_from_xen(void)
|
|
||||||
{
|
|
||||||
struct vcpu_time_info *src;
|
|
||||||
struct shadow_time_info *dst;
|
|
||||||
|
|
||||||
/* src is shared memory with the hypervisor, so we need to
|
|
||||||
make sure we get a consistent snapshot, even in the face of
|
|
||||||
being preempted. */
|
|
||||||
src = &__get_cpu_var(xen_vcpu)->time;
|
|
||||||
dst = &__get_cpu_var(shadow_time);
|
|
||||||
|
|
||||||
do {
|
|
||||||
dst->version = src->version;
|
|
||||||
rmb(); /* fetch version before data */
|
|
||||||
dst->tsc_timestamp = src->tsc_timestamp;
|
|
||||||
dst->system_timestamp = src->system_time;
|
|
||||||
dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
|
|
||||||
dst->tsc_shift = src->tsc_shift;
|
|
||||||
rmb(); /* test version after fetching data */
|
|
||||||
} while ((src->version & 1) | (dst->version ^ src->version));
|
|
||||||
|
|
||||||
return dst->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
|
|
||||||
* yielding a 64-bit result.
|
|
||||||
*/
|
|
||||||
static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
|
|
||||||
{
|
|
||||||
u64 product;
|
|
||||||
#ifdef __i386__
|
|
||||||
u32 tmp1, tmp2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (shift < 0)
|
|
||||||
delta >>= -shift;
|
|
||||||
else
|
|
||||||
delta <<= shift;
|
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
__asm__ (
|
|
||||||
"mul %5 ; "
|
|
||||||
"mov %4,%%eax ; "
|
|
||||||
"mov %%edx,%4 ; "
|
|
||||||
"mul %5 ; "
|
|
||||||
"xor %5,%5 ; "
|
|
||||||
"add %4,%%eax ; "
|
|
||||||
"adc %5,%%edx ; "
|
|
||||||
: "=A" (product), "=r" (tmp1), "=r" (tmp2)
|
|
||||||
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
|
|
||||||
#elif __x86_64__
|
|
||||||
__asm__ (
|
|
||||||
"mul %%rdx ; shrd $32,%%rdx,%%rax"
|
|
||||||
: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
|
|
||||||
#else
|
|
||||||
#error implement me!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 get_nsec_offset(struct shadow_time_info *shadow)
|
|
||||||
{
|
|
||||||
u64 now, delta;
|
|
||||||
now = native_read_tsc();
|
|
||||||
delta = now - shadow->tsc_timestamp;
|
|
||||||
return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cycle_t xen_clocksource_read(void)
|
static cycle_t xen_clocksource_read(void)
|
||||||
{
|
{
|
||||||
struct shadow_time_info *shadow = &get_cpu_var(shadow_time);
|
struct pvclock_vcpu_time_info *src;
|
||||||
cycle_t ret;
|
cycle_t ret;
|
||||||
unsigned version;
|
|
||||||
|
|
||||||
do {
|
|
||||||
version = get_time_values_from_xen();
|
|
||||||
barrier();
|
|
||||||
ret = shadow->system_timestamp + get_nsec_offset(shadow);
|
|
||||||
barrier();
|
|
||||||
} while (version != __get_cpu_var(xen_vcpu)->time.version);
|
|
||||||
|
|
||||||
put_cpu_var(shadow_time);
|
|
||||||
|
|
||||||
|
src = &get_cpu_var(xen_vcpu)->time;
|
||||||
|
ret = pvclock_clocksource_read(src);
|
||||||
|
put_cpu_var(xen_vcpu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xen_read_wallclock(struct timespec *ts)
|
static void xen_read_wallclock(struct timespec *ts)
|
||||||
{
|
{
|
||||||
const struct shared_info *s = HYPERVISOR_shared_info;
|
struct shared_info *s = HYPERVISOR_shared_info;
|
||||||
u32 version;
|
struct pvclock_wall_clock *wall_clock = &(s->wc);
|
||||||
u64 delta;
|
struct pvclock_vcpu_time_info *vcpu_time;
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
/* get wallclock at system boot */
|
vcpu_time = &get_cpu_var(xen_vcpu)->time;
|
||||||
do {
|
pvclock_read_wallclock(wall_clock, vcpu_time, ts);
|
||||||
version = s->wc_version;
|
put_cpu_var(xen_vcpu);
|
||||||
rmb(); /* fetch version before time */
|
|
||||||
now.tv_sec = s->wc_sec;
|
|
||||||
now.tv_nsec = s->wc_nsec;
|
|
||||||
rmb(); /* fetch time before checking version */
|
|
||||||
} while ((s->wc_version & 1) | (version ^ s->wc_version));
|
|
||||||
|
|
||||||
delta = xen_clocksource_read(); /* time since system boot */
|
|
||||||
delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec;
|
|
||||||
|
|
||||||
now.tv_nsec = do_div(delta, NSEC_PER_SEC);
|
|
||||||
now.tv_sec = delta;
|
|
||||||
|
|
||||||
set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long xen_get_wallclock(void)
|
unsigned long xen_get_wallclock(void)
|
||||||
|
@ -345,7 +240,6 @@ unsigned long xen_get_wallclock(void)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
xen_read_wallclock(&ts);
|
xen_read_wallclock(&ts);
|
||||||
|
|
||||||
return ts.tv_sec;
|
return ts.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,8 +463,6 @@ __init void xen_time_init(void)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
get_time_values_from_xen();
|
|
||||||
|
|
||||||
clocksource_register(&xen_clocksource);
|
clocksource_register(&xen_clocksource);
|
||||||
|
|
||||||
if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) {
|
if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ ENTRY(startup_xen)
|
||||||
|
|
||||||
__FINIT
|
__FINIT
|
||||||
|
|
||||||
.pushsection .bss.page_aligned
|
.pushsection .text
|
||||||
.align PAGE_SIZE_asm
|
.align PAGE_SIZE_asm
|
||||||
ENTRY(hypercall_page)
|
ENTRY(hypercall_page)
|
||||||
.skip 0x1000
|
.skip 0x1000
|
||||||
|
@ -30,11 +30,7 @@ ENTRY(hypercall_page)
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long startup_xen)
|
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long startup_xen)
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page)
|
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page)
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb")
|
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb")
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
|
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
|
||||||
#else
|
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "no")
|
|
||||||
#endif
|
|
||||||
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
|
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
|
||||||
|
|
||||||
#endif /*CONFIG_XEN */
|
#endif /*CONFIG_XEN */
|
||||||
|
|
|
@ -389,6 +389,7 @@ static int i915_resume(struct drm_device *dev)
|
||||||
pci_restore_state(dev->pdev);
|
pci_restore_state(dev->pdev);
|
||||||
if (pci_enable_device(dev->pdev))
|
if (pci_enable_device(dev->pdev))
|
||||||
return -1;
|
return -1;
|
||||||
|
pci_set_master(dev->pdev);
|
||||||
|
|
||||||
pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
|
pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
|
||||||
|
|
||||||
|
|
|
@ -981,16 +981,9 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
|
||||||
int n_tty_ioctl(struct tty_struct *tty, struct file *file,
|
int n_tty_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct tty_struct *real_tty;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
|
||||||
tty->driver->subtype == PTY_TYPE_MASTER)
|
|
||||||
real_tty = tty->link;
|
|
||||||
else
|
|
||||||
real_tty = tty;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TCXONC:
|
case TCXONC:
|
||||||
retval = tty_check_change(tty);
|
retval = tty_check_change(tty);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
#include <linux/hwmon-sysfs.h>
|
#include <linux/hwmon-sysfs.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/* uGuru3 bank addresses */
|
/* uGuru3 bank addresses */
|
||||||
|
@ -323,7 +324,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||||
{ "AUX1 Fan", 36, 2, 60, 1, 0 },
|
{ "AUX1 Fan", 36, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0013, "unknown", {
|
{ 0x0013, "Abit AW8D", {
|
||||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||||
{ "DDR", 1, 0, 10, 1, 0 },
|
{ "DDR", 1, 0, 10, 1, 0 },
|
||||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||||
|
@ -349,6 +350,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||||
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
{ "AUX2 Fan", 36, 2, 60, 1, 0 },
|
||||||
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
||||||
{ "AUX4 Fan", 38, 2, 60, 1, 0 },
|
{ "AUX4 Fan", 38, 2, 60, 1, 0 },
|
||||||
|
{ "AUX5 Fan", 39, 2, 60, 1, 0 },
|
||||||
{ NULL, 0, 0, 0, 0, 0 } }
|
{ NULL, 0, 0, 0, 0, 0 } }
|
||||||
},
|
},
|
||||||
{ 0x0014, "Abit AB9 Pro", {
|
{ 0x0014, "Abit AB9 Pro", {
|
||||||
|
@ -1111,11 +1113,12 @@ static int __init abituguru3_detect(void)
|
||||||
{
|
{
|
||||||
/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
|
/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
|
||||||
0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
|
0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
|
||||||
at CMD instead, why is unknown. So we test for 0x05 too. */
|
or 0x55 at CMD instead, why is unknown. */
|
||||||
u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
|
u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
|
||||||
u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
|
u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
|
||||||
if (((data_val == 0x00) || (data_val == 0x08)) &&
|
if (((data_val == 0x00) || (data_val == 0x08)) &&
|
||||||
((cmd_val == 0xAC) || (cmd_val == 0x05)))
|
((cmd_val == 0xAC) || (cmd_val == 0x05) ||
|
||||||
|
(cmd_val == 0x55)))
|
||||||
return ABIT_UGURU3_BASE;
|
return ABIT_UGURU3_BASE;
|
||||||
|
|
||||||
ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
|
ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
|
||||||
|
@ -1138,6 +1141,15 @@ static int __init abituguru3_init(void)
|
||||||
int address, err;
|
int address, err;
|
||||||
struct resource res = { .flags = IORESOURCE_IO };
|
struct resource res = { .flags = IORESOURCE_IO };
|
||||||
|
|
||||||
|
#ifdef CONFIG_DMI
|
||||||
|
const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
|
||||||
|
|
||||||
|
/* safety check, refuse to load on non Abit motherboards */
|
||||||
|
if (!force && (!board_vendor ||
|
||||||
|
strcmp(board_vendor, "http://www.abit.com.tw/")))
|
||||||
|
return -ENODEV;
|
||||||
|
#endif
|
||||||
|
|
||||||
address = abituguru3_detect();
|
address = abituguru3_detect();
|
||||||
if (address < 0)
|
if (address < 0)
|
||||||
return address;
|
return address;
|
||||||
|
|
|
@ -309,6 +309,9 @@ static struct adt7473_data *adt7473_update_device(struct device *dev)
|
||||||
ADT7473_REG_PWM_BHVR(i));
|
ADT7473_REG_PWM_BHVR(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
|
||||||
|
data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
|
||||||
|
|
||||||
data->limits_last_updated = local_jiffies;
|
data->limits_last_updated = local_jiffies;
|
||||||
data->limits_valid = 1;
|
data->limits_valid = 1;
|
||||||
|
|
||||||
|
|
|
@ -251,10 +251,13 @@ static int lm75_detach_client(struct i2c_client *client)
|
||||||
the SMBus standard. */
|
the SMBus standard. */
|
||||||
static int lm75_read_value(struct i2c_client *client, u8 reg)
|
static int lm75_read_value(struct i2c_client *client, u8 reg)
|
||||||
{
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
if (reg == LM75_REG_CONF)
|
if (reg == LM75_REG_CONF)
|
||||||
return i2c_smbus_read_byte_data(client, reg);
|
return i2c_smbus_read_byte_data(client, reg);
|
||||||
else
|
|
||||||
return swab16(i2c_smbus_read_word_data(client, reg));
|
value = i2c_smbus_read_word_data(client, reg);
|
||||||
|
return (value < 0) ? value : swab16(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
|
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
|
||||||
|
@ -287,9 +290,16 @@ static struct lm75_data *lm75_update_device(struct device *dev)
|
||||||
int i;
|
int i;
|
||||||
dev_dbg(&client->dev, "Starting lm75 update\n");
|
dev_dbg(&client->dev, "Starting lm75 update\n");
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(data->temp); i++)
|
for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
|
||||||
data->temp[i] = lm75_read_value(client,
|
int status;
|
||||||
LM75_REG_TEMP[i]);
|
|
||||||
|
status = lm75_read_value(client, LM75_REG_TEMP[i]);
|
||||||
|
if (status < 0)
|
||||||
|
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||||
|
LM75_REG_TEMP[i], status);
|
||||||
|
else
|
||||||
|
data->temp[i] = status;
|
||||||
|
}
|
||||||
data->last_updated = jiffies;
|
data->last_updated = jiffies;
|
||||||
data->valid = 1;
|
data->valid = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,23 +192,20 @@ static int RANGE_TO_REG( int range )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( range < lm85_range_map[0] ) {
|
if (range >= lm85_range_map[15])
|
||||||
return 0 ;
|
|
||||||
} else if ( range > lm85_range_map[15] ) {
|
|
||||||
return 15 ;
|
return 15 ;
|
||||||
} else { /* find closest match */
|
|
||||||
for ( i = 14 ; i >= 0 ; --i ) {
|
/* Find the closest match */
|
||||||
if ( range > lm85_range_map[i] ) { /* range bracketed */
|
for (i = 14; i >= 0; --i) {
|
||||||
if ((lm85_range_map[i+1] - range) <
|
if (range >= lm85_range_map[i]) {
|
||||||
(range - lm85_range_map[i])) {
|
if ((lm85_range_map[i + 1] - range) <
|
||||||
i++;
|
(range - lm85_range_map[i]))
|
||||||
break;
|
return i + 1;
|
||||||
}
|
return i;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return( i & 0x0f );
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
|
#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
page = alloc_pages(gfp_mask, order);
|
/*
|
||||||
|
* Use __GFP_ZERO because buggy firmware assumes ICM pages are
|
||||||
|
* cleared, and subtle failures are seen if they aren't.
|
||||||
|
*/
|
||||||
|
page = alloc_pages(gfp_mask | __GFP_ZERO, order);
|
||||||
if (!page)
|
if (!page)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
|
||||||
* we set it now, so we can trap and pass that trap to the Guest if it
|
* we set it now, so we can trap and pass that trap to the Guest if it
|
||||||
* uses the FPU. */
|
* uses the FPU. */
|
||||||
if (cpu->ts)
|
if (cpu->ts)
|
||||||
lguest_set_ts();
|
unlazy_fpu(current);
|
||||||
|
|
||||||
/* SYSENTER is an optimized way of doing system calls. We can't allow
|
/* SYSENTER is an optimized way of doing system calls. We can't allow
|
||||||
* it because it always jumps to privilege level 0. A normal Guest
|
* it because it always jumps to privilege level 0. A normal Guest
|
||||||
|
@ -196,6 +196,10 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
|
||||||
* trap made the switcher code come back, and an error code which some
|
* trap made the switcher code come back, and an error code which some
|
||||||
* traps set. */
|
* traps set. */
|
||||||
|
|
||||||
|
/* Restore SYSENTER if it's supposed to be on. */
|
||||||
|
if (boot_cpu_has(X86_FEATURE_SEP))
|
||||||
|
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
|
||||||
|
|
||||||
/* If the Guest page faulted, then the cr2 register will tell us the
|
/* If the Guest page faulted, then the cr2 register will tell us the
|
||||||
* bad virtual address. We have to grab this now, because once we
|
* bad virtual address. We have to grab this now, because once we
|
||||||
* re-enable interrupts an interrupt could fault and thus overwrite
|
* re-enable interrupts an interrupt could fault and thus overwrite
|
||||||
|
@ -203,13 +207,12 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
|
||||||
if (cpu->regs->trapnum == 14)
|
if (cpu->regs->trapnum == 14)
|
||||||
cpu->arch.last_pagefault = read_cr2();
|
cpu->arch.last_pagefault = read_cr2();
|
||||||
/* Similarly, if we took a trap because the Guest used the FPU,
|
/* Similarly, if we took a trap because the Guest used the FPU,
|
||||||
* we have to restore the FPU it expects to see. */
|
* we have to restore the FPU it expects to see.
|
||||||
|
* math_state_restore() may sleep and we may even move off to
|
||||||
|
* a different CPU. So all the critical stuff should be done
|
||||||
|
* before this. */
|
||||||
else if (cpu->regs->trapnum == 7)
|
else if (cpu->regs->trapnum == 7)
|
||||||
math_state_restore();
|
math_state_restore();
|
||||||
|
|
||||||
/* Restore SYSENTER if it's supposed to be on. */
|
|
||||||
if (boot_cpu_has(X86_FEATURE_SEP))
|
|
||||||
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*H:130 Now we've examined the hypercall code; our Guest can make requests.
|
/*H:130 Now we've examined the hypercall code; our Guest can make requests.
|
||||||
|
|
|
@ -942,7 +942,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
m->msg_namelen = 0;
|
m->msg_namelen = 0;
|
||||||
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
total_len = min(total_len, skb->len);
|
total_len = min_t(size_t, total_len, skb->len);
|
||||||
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
|
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = total_len;
|
error = total_len;
|
||||||
|
|
|
@ -68,7 +68,6 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
|
||||||
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
|
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
|
||||||
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
|
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
|
||||||
obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
|
obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
|
||||||
CFLAGS_hpwdt.o += -O
|
|
||||||
obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
|
obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
|
||||||
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
|
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
|
||||||
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
|
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
|
||||||
|
|
|
@ -529,7 +529,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
|
||||||
|
|
||||||
#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
|
#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
|
||||||
/* Clear master flag /before/ clearing selector flag. */
|
/* Clear master flag /before/ clearing selector flag. */
|
||||||
rmb();
|
wmb();
|
||||||
#endif
|
#endif
|
||||||
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
|
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
|
||||||
while (pending_words != 0) {
|
while (pending_words != 0) {
|
||||||
|
|
|
@ -855,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Update group descriptor block for new group */
|
/* Update group descriptor block for new group */
|
||||||
gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
|
gdp = (struct ext4_group_desc *)((char *)primary->b_data +
|
||||||
|
gdb_off * EXT4_DESC_SIZE(sb));
|
||||||
|
|
||||||
ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
|
ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
|
||||||
ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
|
ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
|
||||||
|
|
|
@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int zero_metapath_length(const struct metapath *mp,
|
static inline unsigned int metapath_branch_start(const struct metapath *mp)
|
||||||
unsigned height)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
if (mp->mp_list[0] == 0)
|
||||||
for (i = 0; i < height - 1; i++) {
|
return 2;
|
||||||
if (mp->mp_list[i] != 0)
|
return 1;
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||||
struct buffer_head *dibh = mp->mp_bh[0];
|
struct buffer_head *dibh = mp->mp_bh[0];
|
||||||
u64 bn, dblock = 0;
|
u64 bn, dblock = 0;
|
||||||
unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0;
|
unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
|
||||||
unsigned dblks = 0;
|
unsigned dblks = 0;
|
||||||
unsigned ptrs_per_blk;
|
unsigned ptrs_per_blk;
|
||||||
const unsigned end_of_metadata = height - 1;
|
const unsigned end_of_metadata = height - 1;
|
||||||
|
@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
|
||||||
/* Building up tree height */
|
/* Building up tree height */
|
||||||
state = ALLOC_GROW_HEIGHT;
|
state = ALLOC_GROW_HEIGHT;
|
||||||
iblks = height - ip->i_height;
|
iblks = height - ip->i_height;
|
||||||
zmpl = zero_metapath_length(mp, height);
|
branch_start = metapath_branch_start(mp);
|
||||||
iblks -= zmpl;
|
iblks += (height - branch_start);
|
||||||
iblks += height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
|
||||||
sizeof(struct gfs2_meta_header));
|
sizeof(struct gfs2_meta_header));
|
||||||
*ptr = zero_bn;
|
*ptr = zero_bn;
|
||||||
state = ALLOC_GROW_DEPTH;
|
state = ALLOC_GROW_DEPTH;
|
||||||
for(i = zmpl; i < height; i++) {
|
for(i = branch_start; i < height; i++) {
|
||||||
if (mp->mp_bh[i] == NULL)
|
if (mp->mp_bh[i] == NULL)
|
||||||
break;
|
break;
|
||||||
brelse(mp->mp_bh[i]);
|
brelse(mp->mp_bh[i]);
|
||||||
mp->mp_bh[i] = NULL;
|
mp->mp_bh[i] = NULL;
|
||||||
}
|
}
|
||||||
i = zmpl;
|
i = branch_start;
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -195,7 +195,7 @@ static u32 gfs2_bitfit(const u8 *buffer, unsigned int buflen, u32 goal,
|
||||||
depending on architecture. I've experimented with several ways
|
depending on architecture. I've experimented with several ways
|
||||||
of writing this section such as using an else before the goto
|
of writing this section such as using an else before the goto
|
||||||
but this one seems to be the fastest. */
|
but this one seems to be the fastest. */
|
||||||
while ((unsigned char *)plong < end - 1) {
|
while ((unsigned char *)plong < end - sizeof(unsigned long)) {
|
||||||
prefetch(plong + 1);
|
prefetch(plong + 1);
|
||||||
if (((*plong) & LBITMASK) != lskipval)
|
if (((*plong) & LBITMASK) != lskipval)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
|
||||||
struct mnt_fhstatus *res)
|
struct mnt_fhstatus *res)
|
||||||
{
|
{
|
||||||
struct nfs_fh *fh = res->fh;
|
struct nfs_fh *fh = res->fh;
|
||||||
|
unsigned size;
|
||||||
|
|
||||||
if ((res->status = ntohl(*p++)) == 0) {
|
if ((res->status = ntohl(*p++)) == 0) {
|
||||||
int size = ntohl(*p++);
|
size = ntohl(*p++);
|
||||||
if (size <= NFS3_FHSIZE) {
|
if (size <= NFS3_FHSIZE && size != 0) {
|
||||||
fh->size = size;
|
fh->size = size;
|
||||||
memcpy(fh->data, p, size);
|
memcpy(fh->data, p, size);
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options,
|
||||||
{
|
{
|
||||||
struct nfs_mount_data *data = (struct nfs_mount_data *)options;
|
struct nfs_mount_data *data = (struct nfs_mount_data *)options;
|
||||||
|
|
||||||
memset(args, 0, sizeof(*args));
|
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
goto out_no_data;
|
goto out_no_data;
|
||||||
|
|
||||||
|
@ -1251,13 +1249,13 @@ static int nfs_validate_mount_data(void *options,
|
||||||
case 5:
|
case 5:
|
||||||
memset(data->context, 0, sizeof(data->context));
|
memset(data->context, 0, sizeof(data->context));
|
||||||
case 6:
|
case 6:
|
||||||
if (data->flags & NFS_MOUNT_VER3)
|
if (data->flags & NFS_MOUNT_VER3) {
|
||||||
|
if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
|
||||||
|
goto out_invalid_fh;
|
||||||
mntfh->size = data->root.size;
|
mntfh->size = data->root.size;
|
||||||
else
|
} else
|
||||||
mntfh->size = NFS2_FHSIZE;
|
mntfh->size = NFS2_FHSIZE;
|
||||||
|
|
||||||
if (mntfh->size > sizeof(mntfh->data))
|
|
||||||
goto out_invalid_fh;
|
|
||||||
|
|
||||||
memcpy(mntfh->data, data->root.data, mntfh->size);
|
memcpy(mntfh->data, data->root.data, mntfh->size);
|
||||||
if (mntfh->size < sizeof(mntfh->data))
|
if (mntfh->size < sizeof(mntfh->data))
|
||||||
|
@ -1585,24 +1583,29 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
||||||
{
|
{
|
||||||
struct nfs_server *server = NULL;
|
struct nfs_server *server = NULL;
|
||||||
struct super_block *s;
|
struct super_block *s;
|
||||||
struct nfs_fh mntfh;
|
struct nfs_parsed_mount_data *data;
|
||||||
struct nfs_parsed_mount_data data;
|
struct nfs_fh *mntfh;
|
||||||
struct dentry *mntroot;
|
struct dentry *mntroot;
|
||||||
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
|
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
|
||||||
struct nfs_sb_mountdata sb_mntdata = {
|
struct nfs_sb_mountdata sb_mntdata = {
|
||||||
.mntflags = flags,
|
.mntflags = flags,
|
||||||
};
|
};
|
||||||
int error;
|
int error = -ENOMEM;
|
||||||
|
|
||||||
security_init_mnt_opts(&data.lsm_opts);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
|
mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
|
||||||
|
if (data == NULL || mntfh == NULL)
|
||||||
|
goto out_free_fh;
|
||||||
|
|
||||||
|
security_init_mnt_opts(&data->lsm_opts);
|
||||||
|
|
||||||
/* Validate the mount data */
|
/* Validate the mount data */
|
||||||
error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
|
error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Get a volume representation */
|
/* Get a volume representation */
|
||||||
server = nfs_create_server(&data, &mntfh);
|
server = nfs_create_server(data, mntfh);
|
||||||
if (IS_ERR(server)) {
|
if (IS_ERR(server)) {
|
||||||
error = PTR_ERR(server);
|
error = PTR_ERR(server);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1630,16 +1633,16 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
||||||
|
|
||||||
if (!s->s_root) {
|
if (!s->s_root) {
|
||||||
/* initial superblock/root creation */
|
/* initial superblock/root creation */
|
||||||
nfs_fill_super(s, &data);
|
nfs_fill_super(s, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
mntroot = nfs_get_root(s, &mntfh);
|
mntroot = nfs_get_root(s, mntfh);
|
||||||
if (IS_ERR(mntroot)) {
|
if (IS_ERR(mntroot)) {
|
||||||
error = PTR_ERR(mntroot);
|
error = PTR_ERR(mntroot);
|
||||||
goto error_splat_super;
|
goto error_splat_super;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = security_sb_set_mnt_opts(s, &data.lsm_opts);
|
error = security_sb_set_mnt_opts(s, &data->lsm_opts);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_root;
|
goto error_splat_root;
|
||||||
|
|
||||||
|
@ -1649,9 +1652,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(data.nfs_server.hostname);
|
kfree(data->nfs_server.hostname);
|
||||||
kfree(data.mount_server.hostname);
|
kfree(data->mount_server.hostname);
|
||||||
security_free_mnt_opts(&data.lsm_opts);
|
security_free_mnt_opts(&data->lsm_opts);
|
||||||
|
out_free_fh:
|
||||||
|
kfree(mntfh);
|
||||||
|
kfree(data);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
out_err_nosb:
|
out_err_nosb:
|
||||||
|
@ -1800,8 +1806,6 @@ static int nfs4_validate_mount_data(void *options,
|
||||||
struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
|
struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
memset(args, 0, sizeof(*args));
|
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
goto out_no_data;
|
goto out_no_data;
|
||||||
|
|
||||||
|
@ -1959,26 +1963,31 @@ static int nfs4_validate_mount_data(void *options,
|
||||||
static int nfs4_get_sb(struct file_system_type *fs_type,
|
static int nfs4_get_sb(struct file_system_type *fs_type,
|
||||||
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
|
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
|
||||||
{
|
{
|
||||||
struct nfs_parsed_mount_data data;
|
struct nfs_parsed_mount_data *data;
|
||||||
struct super_block *s;
|
struct super_block *s;
|
||||||
struct nfs_server *server;
|
struct nfs_server *server;
|
||||||
struct nfs_fh mntfh;
|
struct nfs_fh *mntfh;
|
||||||
struct dentry *mntroot;
|
struct dentry *mntroot;
|
||||||
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
|
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
|
||||||
struct nfs_sb_mountdata sb_mntdata = {
|
struct nfs_sb_mountdata sb_mntdata = {
|
||||||
.mntflags = flags,
|
.mntflags = flags,
|
||||||
};
|
};
|
||||||
int error;
|
int error = -ENOMEM;
|
||||||
|
|
||||||
security_init_mnt_opts(&data.lsm_opts);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
|
mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
|
||||||
|
if (data == NULL || mntfh == NULL)
|
||||||
|
goto out_free_fh;
|
||||||
|
|
||||||
|
security_init_mnt_opts(&data->lsm_opts);
|
||||||
|
|
||||||
/* Validate the mount data */
|
/* Validate the mount data */
|
||||||
error = nfs4_validate_mount_data(raw_data, &data, dev_name);
|
error = nfs4_validate_mount_data(raw_data, data, dev_name);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Get a volume representation */
|
/* Get a volume representation */
|
||||||
server = nfs4_create_server(&data, &mntfh);
|
server = nfs4_create_server(data, mntfh);
|
||||||
if (IS_ERR(server)) {
|
if (IS_ERR(server)) {
|
||||||
error = PTR_ERR(server);
|
error = PTR_ERR(server);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2009,13 +2018,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
||||||
nfs4_fill_super(s);
|
nfs4_fill_super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
mntroot = nfs4_get_root(s, &mntfh);
|
mntroot = nfs4_get_root(s, mntfh);
|
||||||
if (IS_ERR(mntroot)) {
|
if (IS_ERR(mntroot)) {
|
||||||
error = PTR_ERR(mntroot);
|
error = PTR_ERR(mntroot);
|
||||||
goto error_splat_super;
|
goto error_splat_super;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = security_sb_set_mnt_opts(s, &data.lsm_opts);
|
error = security_sb_set_mnt_opts(s, &data->lsm_opts);
|
||||||
if (error)
|
if (error)
|
||||||
goto error_splat_root;
|
goto error_splat_root;
|
||||||
|
|
||||||
|
@ -2025,10 +2034,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(data.client_address);
|
kfree(data->client_address);
|
||||||
kfree(data.nfs_server.export_path);
|
kfree(data->nfs_server.export_path);
|
||||||
kfree(data.nfs_server.hostname);
|
kfree(data->nfs_server.hostname);
|
||||||
security_free_mnt_opts(&data.lsm_opts);
|
security_free_mnt_opts(&data->lsm_opts);
|
||||||
|
out_free_fh:
|
||||||
|
kfree(mntfh);
|
||||||
|
kfree(data);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
|
|
@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page,
|
||||||
}
|
}
|
||||||
|
|
||||||
status = nfs_writepage_setup(ctx, page, offset, count);
|
status = nfs_writepage_setup(ctx, page, offset, count);
|
||||||
__set_page_dirty_nobuffers(page);
|
if (status < 0)
|
||||||
|
nfs_set_pageerror(page);
|
||||||
|
else
|
||||||
|
__set_page_dirty_nobuffers(page);
|
||||||
|
|
||||||
dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
|
dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
|
||||||
status, (long long)i_size_read(inode));
|
status, (long long)i_size_read(inode));
|
||||||
if (status < 0)
|
|
||||||
nfs_set_pageerror(page);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
|
||||||
retval++;
|
retval++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cond_resched();
|
|
||||||
}
|
}
|
||||||
if (res_in)
|
if (res_in)
|
||||||
*rinp = res_in;
|
*rinp = res_in;
|
||||||
|
@ -257,6 +256,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
|
||||||
*routp = res_out;
|
*routp = res_out;
|
||||||
if (res_ex)
|
if (res_ex)
|
||||||
*rexp = res_ex;
|
*rexp = res_ex;
|
||||||
|
cond_resched();
|
||||||
}
|
}
|
||||||
wait = NULL;
|
wait = NULL;
|
||||||
if (retval || !*timeout || signal_pending(current))
|
if (retval || !*timeout || signal_pending(current))
|
||||||
|
|
|
@ -261,7 +261,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline int __mcpcia_is_mmio(unsigned long addr)
|
extern inline int __mcpcia_is_mmio(unsigned long addr)
|
||||||
{
|
{
|
||||||
return (addr & 0x80000000UL) == 0;
|
return (addr & 0x80000000UL) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,13 +356,13 @@ struct el_t2_frame_corrected {
|
||||||
#define vip volatile int *
|
#define vip volatile int *
|
||||||
#define vuip volatile unsigned int *
|
#define vuip volatile unsigned int *
|
||||||
|
|
||||||
static inline u8 t2_inb(unsigned long addr)
|
extern inline u8 t2_inb(unsigned long addr)
|
||||||
{
|
{
|
||||||
long result = *(vip) ((addr << 5) + T2_IO + 0x00);
|
long result = *(vip) ((addr << 5) + T2_IO + 0x00);
|
||||||
return __kernel_extbl(result, addr & 3);
|
return __kernel_extbl(result, addr & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void t2_outb(u8 b, unsigned long addr)
|
extern inline void t2_outb(u8 b, unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned long w;
|
unsigned long w;
|
||||||
|
|
||||||
|
@ -371,13 +371,13 @@ static inline void t2_outb(u8 b, unsigned long addr)
|
||||||
mb();
|
mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u16 t2_inw(unsigned long addr)
|
extern inline u16 t2_inw(unsigned long addr)
|
||||||
{
|
{
|
||||||
long result = *(vip) ((addr << 5) + T2_IO + 0x08);
|
long result = *(vip) ((addr << 5) + T2_IO + 0x08);
|
||||||
return __kernel_extwl(result, addr & 3);
|
return __kernel_extwl(result, addr & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void t2_outw(u16 b, unsigned long addr)
|
extern inline void t2_outw(u16 b, unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned long w;
|
unsigned long w;
|
||||||
|
|
||||||
|
@ -386,12 +386,12 @@ static inline void t2_outw(u16 b, unsigned long addr)
|
||||||
mb();
|
mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 t2_inl(unsigned long addr)
|
extern inline u32 t2_inl(unsigned long addr)
|
||||||
{
|
{
|
||||||
return *(vuip) ((addr << 5) + T2_IO + 0x18);
|
return *(vuip) ((addr << 5) + T2_IO + 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void t2_outl(u32 b, unsigned long addr)
|
extern inline void t2_outl(u32 b, unsigned long addr)
|
||||||
{
|
{
|
||||||
*(vuip) ((addr << 5) + T2_IO + 0x18) = b;
|
*(vuip) ((addr << 5) + T2_IO + 0x18) = b;
|
||||||
mb();
|
mb();
|
||||||
|
@ -435,7 +435,7 @@ static inline void t2_outl(u32 b, unsigned long addr)
|
||||||
set_hae(msb); \
|
set_hae(msb); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(t2_hae_lock);
|
extern spinlock_t t2_hae_lock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
|
* NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
* register not being up-to-date with respect to the hardware
|
* register not being up-to-date with respect to the hardware
|
||||||
* value.
|
* value.
|
||||||
*/
|
*/
|
||||||
static inline void __set_hae(unsigned long new_hae)
|
extern inline void __set_hae(unsigned long new_hae)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
@ -49,7 +49,7 @@ static inline void __set_hae(unsigned long new_hae)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_hae(unsigned long new_hae)
|
extern inline void set_hae(unsigned long new_hae)
|
||||||
{
|
{
|
||||||
if (new_hae != alpha_mv.hae_cache)
|
if (new_hae != alpha_mv.hae_cache)
|
||||||
__set_hae(new_hae);
|
__set_hae(new_hae);
|
||||||
|
@ -176,7 +176,7 @@ REMAP2(u64, writeq, volatile)
|
||||||
#undef REMAP1
|
#undef REMAP1
|
||||||
#undef REMAP2
|
#undef REMAP2
|
||||||
|
|
||||||
static inline void __iomem *generic_ioportmap(unsigned long a)
|
extern inline void __iomem *generic_ioportmap(unsigned long a)
|
||||||
{
|
{
|
||||||
return alpha_mv.mv_ioportmap(a);
|
return alpha_mv.mv_ioportmap(a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern inline unsigned long
|
static inline unsigned long
|
||||||
__reload_thread(struct pcb_struct *pcb)
|
__reload_thread(struct pcb_struct *pcb)
|
||||||
{
|
{
|
||||||
register unsigned long a0 __asm__("$16");
|
register unsigned long a0 __asm__("$16");
|
||||||
|
@ -114,7 +114,7 @@ extern unsigned long last_asn;
|
||||||
#define __MMU_EXTERN_INLINE
|
#define __MMU_EXTERN_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline unsigned long
|
extern inline unsigned long
|
||||||
__get_new_mm_context(struct mm_struct *mm, long cpu)
|
__get_new_mm_context(struct mm_struct *mm, long cpu)
|
||||||
{
|
{
|
||||||
unsigned long asn = cpu_last_asn(cpu);
|
unsigned long asn = cpu_last_asn(cpu);
|
||||||
|
@ -226,7 +226,7 @@ ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern inline int
|
static inline int
|
||||||
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -1,6 +1,78 @@
|
||||||
#ifndef __ALPHA_PERCPU_H
|
#ifndef __ALPHA_PERCPU_H
|
||||||
#define __ALPHA_PERCPU_H
|
#define __ALPHA_PERCPU_H
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/threads.h>
|
||||||
|
|
||||||
#include <asm-generic/percpu.h>
|
/*
|
||||||
|
* Determine the real variable name from the name visible in the
|
||||||
|
* kernel sources.
|
||||||
|
*/
|
||||||
|
#define per_cpu_var(var) per_cpu__##var
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* per_cpu_offset() is the offset that has to be added to a
|
||||||
|
* percpu variable to get to the instance for a certain processor.
|
||||||
|
*/
|
||||||
|
extern unsigned long __per_cpu_offset[NR_CPUS];
|
||||||
|
|
||||||
|
#define per_cpu_offset(x) (__per_cpu_offset[x])
|
||||||
|
|
||||||
|
#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
|
||||||
|
#ifdef CONFIG_DEBUG_PREEMPT
|
||||||
|
#define my_cpu_offset per_cpu_offset(smp_processor_id())
|
||||||
|
#else
|
||||||
|
#define my_cpu_offset __my_cpu_offset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MODULE
|
||||||
|
#define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
|
||||||
|
#define PER_CPU_ATTRIBUTES
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* To calculate addresses of locally defined variables, GCC uses 32-bit
|
||||||
|
* displacement from the GP. Which doesn't work for per cpu variables in
|
||||||
|
* modules, as an offset to the kernel per cpu area is way above 4G.
|
||||||
|
*
|
||||||
|
* This forces allocation of a GOT entry for per cpu variable using
|
||||||
|
* ldq instruction with a 'literal' relocation.
|
||||||
|
*/
|
||||||
|
#define SHIFT_PERCPU_PTR(var, offset) ({ \
|
||||||
|
extern int simple_identifier_##var(void); \
|
||||||
|
unsigned long __ptr, tmp_gp; \
|
||||||
|
asm ( "br %1, 1f \n\
|
||||||
|
1: ldgp %1, 0(%1) \n\
|
||||||
|
ldq %0, per_cpu__" #var"(%1)\t!literal" \
|
||||||
|
: "=&r"(__ptr), "=&r"(tmp_gp)); \
|
||||||
|
(typeof(&per_cpu_var(var)))(__ptr + (offset)); })
|
||||||
|
|
||||||
|
#define PER_CPU_ATTRIBUTES __used
|
||||||
|
|
||||||
|
#endif /* MODULE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A percpu variable may point to a discarded regions. The following are
|
||||||
|
* established ways to produce a usable pointer from the percpu variable
|
||||||
|
* offset.
|
||||||
|
*/
|
||||||
|
#define per_cpu(var, cpu) \
|
||||||
|
(*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu)))
|
||||||
|
#define __get_cpu_var(var) \
|
||||||
|
(*SHIFT_PERCPU_PTR(var, my_cpu_offset))
|
||||||
|
#define __raw_get_cpu_var(var) \
|
||||||
|
(*SHIFT_PERCPU_PTR(var, __my_cpu_offset))
|
||||||
|
|
||||||
|
#else /* ! SMP */
|
||||||
|
|
||||||
|
#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var)))
|
||||||
|
#define __get_cpu_var(var) per_cpu_var(var)
|
||||||
|
#define __raw_get_cpu_var(var) per_cpu_var(var)
|
||||||
|
|
||||||
|
#define PER_CPU_ATTRIBUTES
|
||||||
|
|
||||||
|
#endif /* SMP */
|
||||||
|
|
||||||
|
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
|
||||||
|
|
||||||
#endif /* __ALPHA_PERCPU_H */
|
#endif /* __ALPHA_PERCPU_H */
|
||||||
|
|
|
@ -184,7 +184,7 @@ enum amask_enum {
|
||||||
__amask; })
|
__amask; })
|
||||||
|
|
||||||
#define __CALL_PAL_R0(NAME, TYPE) \
|
#define __CALL_PAL_R0(NAME, TYPE) \
|
||||||
static inline TYPE NAME(void) \
|
extern inline TYPE NAME(void) \
|
||||||
{ \
|
{ \
|
||||||
register TYPE __r0 __asm__("$0"); \
|
register TYPE __r0 __asm__("$0"); \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
|
@ -196,7 +196,7 @@ static inline TYPE NAME(void) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __CALL_PAL_W1(NAME, TYPE0) \
|
#define __CALL_PAL_W1(NAME, TYPE0) \
|
||||||
static inline void NAME(TYPE0 arg0) \
|
extern inline void NAME(TYPE0 arg0) \
|
||||||
{ \
|
{ \
|
||||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
|
@ -207,7 +207,7 @@ static inline void NAME(TYPE0 arg0) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __CALL_PAL_W2(NAME, TYPE0, TYPE1) \
|
#define __CALL_PAL_W2(NAME, TYPE0, TYPE1) \
|
||||||
static inline void NAME(TYPE0 arg0, TYPE1 arg1) \
|
extern inline void NAME(TYPE0 arg0, TYPE1 arg1) \
|
||||||
{ \
|
{ \
|
||||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||||
register TYPE1 __r17 __asm__("$17") = arg1; \
|
register TYPE1 __r17 __asm__("$17") = arg1; \
|
||||||
|
@ -219,7 +219,7 @@ static inline void NAME(TYPE0 arg0, TYPE1 arg1) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __CALL_PAL_RW1(NAME, RTYPE, TYPE0) \
|
#define __CALL_PAL_RW1(NAME, RTYPE, TYPE0) \
|
||||||
static inline RTYPE NAME(TYPE0 arg0) \
|
extern inline RTYPE NAME(TYPE0 arg0) \
|
||||||
{ \
|
{ \
|
||||||
register RTYPE __r0 __asm__("$0"); \
|
register RTYPE __r0 __asm__("$0"); \
|
||||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||||
|
@ -232,7 +232,7 @@ static inline RTYPE NAME(TYPE0 arg0) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1) \
|
#define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1) \
|
||||||
static inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \
|
extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \
|
||||||
{ \
|
{ \
|
||||||
register RTYPE __r0 __asm__("$0"); \
|
register RTYPE __r0 __asm__("$0"); \
|
||||||
register TYPE0 __r16 __asm__("$16") = arg0; \
|
register TYPE0 __r16 __asm__("$16") = arg0; \
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#define VT_BUF_HAVE_MEMSETW
|
#define VT_BUF_HAVE_MEMSETW
|
||||||
#define VT_BUF_HAVE_MEMCPYW
|
#define VT_BUF_HAVE_MEMCPYW
|
||||||
|
|
||||||
extern inline void scr_writew(u16 val, volatile u16 *addr)
|
static inline void scr_writew(u16 val, volatile u16 *addr)
|
||||||
{
|
{
|
||||||
if (__is_ioaddr(addr))
|
if (__is_ioaddr(addr))
|
||||||
__raw_writew(val, (volatile u16 __iomem *) addr);
|
__raw_writew(val, (volatile u16 __iomem *) addr);
|
||||||
|
@ -21,7 +21,7 @@ extern inline void scr_writew(u16 val, volatile u16 *addr)
|
||||||
*addr = val;
|
*addr = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline u16 scr_readw(volatile const u16 *addr)
|
static inline u16 scr_readw(volatile const u16 *addr)
|
||||||
{
|
{
|
||||||
if (__is_ioaddr(addr))
|
if (__is_ioaddr(addr))
|
||||||
return __raw_readw((volatile const u16 __iomem *) addr);
|
return __raw_readw((volatile const u16 __iomem *) addr);
|
||||||
|
@ -29,7 +29,7 @@ extern inline u16 scr_readw(volatile const u16 *addr)
|
||||||
return *addr;
|
return *addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
|
static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
|
||||||
{
|
{
|
||||||
if (__is_ioaddr(s))
|
if (__is_ioaddr(s))
|
||||||
memsetw_io((u16 __iomem *) s, c, count);
|
memsetw_io((u16 __iomem *) s, c, count);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/kvm_para.h>
|
#include <linux/kvm_para.h>
|
||||||
#include <linux/kvm_types.h>
|
#include <linux/kvm_types.h>
|
||||||
|
|
||||||
|
#include <asm/pvclock-abi.h>
|
||||||
#include <asm/desc.h>
|
#include <asm/desc.h>
|
||||||
|
|
||||||
#define KVM_MAX_VCPUS 16
|
#define KVM_MAX_VCPUS 16
|
||||||
|
@ -282,7 +283,8 @@ struct kvm_vcpu_arch {
|
||||||
struct x86_emulate_ctxt emulate_ctxt;
|
struct x86_emulate_ctxt emulate_ctxt;
|
||||||
|
|
||||||
gpa_t time;
|
gpa_t time;
|
||||||
struct kvm_vcpu_time_info hv_clock;
|
struct pvclock_vcpu_time_info hv_clock;
|
||||||
|
unsigned int hv_clock_tsc_khz;
|
||||||
unsigned int time_offset;
|
unsigned int time_offset;
|
||||||
struct page *time_page;
|
struct page *time_page;
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,24 +48,6 @@ struct kvm_mmu_op_release_pt {
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
/* xen binary-compatible interface. See xen headers for details */
|
|
||||||
struct kvm_vcpu_time_info {
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t pad0;
|
|
||||||
uint64_t tsc_timestamp;
|
|
||||||
uint64_t system_time;
|
|
||||||
uint32_t tsc_to_system_mul;
|
|
||||||
int8_t tsc_shift;
|
|
||||||
int8_t pad[3];
|
|
||||||
} __attribute__((__packed__)); /* 32 bytes */
|
|
||||||
|
|
||||||
struct kvm_wall_clock {
|
|
||||||
uint32_t wc_version;
|
|
||||||
uint32_t wc_sec;
|
|
||||||
uint32_t wc_nsec;
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
|
|
||||||
extern void kvmclock_init(void);
|
extern void kvmclock_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef _ASM_X86_PVCLOCK_ABI_H_
|
||||||
|
#define _ASM_X86_PVCLOCK_ABI_H_
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These structs MUST NOT be changed.
|
||||||
|
* They are the ABI between hypervisor and guest OS.
|
||||||
|
* Both Xen and KVM are using this.
|
||||||
|
*
|
||||||
|
* pvclock_vcpu_time_info holds the system time and the tsc timestamp
|
||||||
|
* of the last update. So the guest can use the tsc delta to get a
|
||||||
|
* more precise system time. There is one per virtual cpu.
|
||||||
|
*
|
||||||
|
* pvclock_wall_clock references the point in time when the system
|
||||||
|
* time was zero (usually boot time), thus the guest calculates the
|
||||||
|
* current wall clock by adding the system time.
|
||||||
|
*
|
||||||
|
* Protocol for the "version" fields is: hypervisor raises it (making
|
||||||
|
* it uneven) before it starts updating the fields and raises it again
|
||||||
|
* (making it even) when it is done. Thus the guest can make sure the
|
||||||
|
* time values it got are consistent by checking the version before
|
||||||
|
* and after reading them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct pvclock_vcpu_time_info {
|
||||||
|
u32 version;
|
||||||
|
u32 pad0;
|
||||||
|
u64 tsc_timestamp;
|
||||||
|
u64 system_time;
|
||||||
|
u32 tsc_to_system_mul;
|
||||||
|
s8 tsc_shift;
|
||||||
|
u8 pad[3];
|
||||||
|
} __attribute__((__packed__)); /* 32 bytes */
|
||||||
|
|
||||||
|
struct pvclock_wall_clock {
|
||||||
|
u32 version;
|
||||||
|
u32 sec;
|
||||||
|
u32 nsec;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
#endif /* _ASM_X86_PVCLOCK_ABI_H_ */
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef _ASM_X86_PVCLOCK_H_
|
||||||
|
#define _ASM_X86_PVCLOCK_H_
|
||||||
|
|
||||||
|
#include <linux/clocksource.h>
|
||||||
|
#include <asm/pvclock-abi.h>
|
||||||
|
|
||||||
|
/* some helper functions for xen and kvm pv clock sources */
|
||||||
|
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
|
||||||
|
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
|
||||||
|
struct pvclock_vcpu_time_info *vcpu,
|
||||||
|
struct timespec *ts);
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PVCLOCK_H_ */
|
|
@ -150,13 +150,9 @@ static inline pte_t __pte_ma(pteval_t x)
|
||||||
return (pte_t) { .pte = x };
|
return (pte_t) { .pte = x };
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
#define pmd_val_ma(v) ((v).pmd)
|
#define pmd_val_ma(v) ((v).pmd)
|
||||||
#define pud_val_ma(v) ((v).pgd.pgd)
|
#define pud_val_ma(v) ((v).pgd.pgd)
|
||||||
#define __pmd_ma(x) ((pmd_t) { (x) } )
|
#define __pmd_ma(x) ((pmd_t) { (x) } )
|
||||||
#else /* !X86_PAE */
|
|
||||||
#define pmd_val_ma(v) ((v).pud.pgd.pgd)
|
|
||||||
#endif /* CONFIG_X86_PAE */
|
|
||||||
|
|
||||||
#define pgd_val_ma(x) ((x).pgd)
|
#define pgd_val_ma(x) ((x).pgd)
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ extern unsigned long init_bootmem_node(pg_data_t *pgdat,
|
||||||
unsigned long freepfn,
|
unsigned long freepfn,
|
||||||
unsigned long startpfn,
|
unsigned long startpfn,
|
||||||
unsigned long endpfn);
|
unsigned long endpfn);
|
||||||
extern void reserve_bootmem_node(pg_data_t *pgdat,
|
extern int reserve_bootmem_node(pg_data_t *pgdat,
|
||||||
unsigned long physaddr,
|
unsigned long physaddr,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define KVM_REQ_REPORT_TPR_ACCESS 2
|
#define KVM_REQ_REPORT_TPR_ACCESS 2
|
||||||
#define KVM_REQ_MMU_RELOAD 3
|
#define KVM_REQ_MMU_RELOAD 3
|
||||||
#define KVM_REQ_TRIPLE_FAULT 4
|
#define KVM_REQ_TRIPLE_FAULT 4
|
||||||
|
#define KVM_REQ_PENDING_TIMER 5
|
||||||
|
|
||||||
struct kvm_vcpu;
|
struct kvm_vcpu;
|
||||||
extern struct kmem_cache *kvm_vcpu_cache;
|
extern struct kmem_cache *kvm_vcpu_cache;
|
||||||
|
|
|
@ -27,8 +27,7 @@
|
||||||
* This routine is called by the kernel to write a series of
|
* This routine is called by the kernel to write a series of
|
||||||
* characters to the tty device. The characters may come from
|
* characters to the tty device. The characters may come from
|
||||||
* user space or kernel space. This routine will return the
|
* user space or kernel space. This routine will return the
|
||||||
* number of characters actually accepted for writing. This
|
* number of characters actually accepted for writing.
|
||||||
* routine is mandatory.
|
|
||||||
*
|
*
|
||||||
* Optional: Required for writable devices.
|
* Optional: Required for writable devices.
|
||||||
*
|
*
|
||||||
|
@ -134,7 +133,7 @@
|
||||||
* This routine notifies the tty driver that it should hangup the
|
* This routine notifies the tty driver that it should hangup the
|
||||||
* tty device.
|
* tty device.
|
||||||
*
|
*
|
||||||
* Required:
|
* Optional:
|
||||||
*
|
*
|
||||||
* void (*break_ctl)(struct tty_stuct *tty, int state);
|
* void (*break_ctl)(struct tty_stuct *tty, int state);
|
||||||
*
|
*
|
||||||
|
|
|
@ -367,6 +367,12 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
|
||||||
a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
|
a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int ipv6_addr_loopback(const struct in6_addr *a)
|
||||||
|
{
|
||||||
|
return ((a->s6_addr32[0] | a->s6_addr32[1] |
|
||||||
|
a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
|
static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
|
||||||
{
|
{
|
||||||
return ((a->s6_addr32[0] | a->s6_addr32[1] |
|
return ((a->s6_addr32[0] | a->s6_addr32[1] |
|
||||||
|
|
|
@ -95,6 +95,11 @@ extern struct list_head net_namespace_list;
|
||||||
#ifdef CONFIG_NET_NS
|
#ifdef CONFIG_NET_NS
|
||||||
extern void __put_net(struct net *net);
|
extern void __put_net(struct net *net);
|
||||||
|
|
||||||
|
static inline int net_alive(struct net *net)
|
||||||
|
{
|
||||||
|
return net && atomic_read(&net->count);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct net *get_net(struct net *net)
|
static inline struct net *get_net(struct net *net)
|
||||||
{
|
{
|
||||||
atomic_inc(&net->count);
|
atomic_inc(&net->count);
|
||||||
|
@ -125,6 +130,12 @@ int net_eq(const struct net *net1, const struct net *net2)
|
||||||
return net1 == net2;
|
return net1 == net2;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
static inline int net_alive(struct net *net)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct net *get_net(struct net *net)
|
static inline struct net *get_net(struct net *net)
|
||||||
{
|
{
|
||||||
return net;
|
return net;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define __XEN_PUBLIC_XEN_H__
|
#define __XEN_PUBLIC_XEN_H__
|
||||||
|
|
||||||
#include <asm/xen/interface.h>
|
#include <asm/xen/interface.h>
|
||||||
|
#include <asm/pvclock-abi.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
|
* XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
|
||||||
|
@ -336,7 +337,7 @@ struct vcpu_info {
|
||||||
uint8_t evtchn_upcall_mask;
|
uint8_t evtchn_upcall_mask;
|
||||||
unsigned long evtchn_pending_sel;
|
unsigned long evtchn_pending_sel;
|
||||||
struct arch_vcpu_info arch;
|
struct arch_vcpu_info arch;
|
||||||
struct vcpu_time_info time;
|
struct pvclock_vcpu_time_info time;
|
||||||
}; /* 64 bytes (x86) */
|
}; /* 64 bytes (x86) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -384,9 +385,7 @@ struct shared_info {
|
||||||
* Wallclock time: updated only by control software. Guests should base
|
* Wallclock time: updated only by control software. Guests should base
|
||||||
* their gettimeofday() syscall on this wallclock-base value.
|
* their gettimeofday() syscall on this wallclock-base value.
|
||||||
*/
|
*/
|
||||||
uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */
|
struct pvclock_wall_clock wc;
|
||||||
uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
|
|
||||||
uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */
|
|
||||||
|
|
||||||
struct arch_shared_info arch;
|
struct arch_shared_info arch;
|
||||||
|
|
||||||
|
|
|
@ -1096,21 +1096,64 @@ static void unqueue_me_pi(struct futex_q *q)
|
||||||
* private futexes.
|
* private futexes.
|
||||||
*/
|
*/
|
||||||
static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
|
static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
|
||||||
struct task_struct *newowner)
|
struct task_struct *newowner,
|
||||||
|
struct rw_semaphore *fshared)
|
||||||
{
|
{
|
||||||
u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
|
u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
|
||||||
struct futex_pi_state *pi_state = q->pi_state;
|
struct futex_pi_state *pi_state = q->pi_state;
|
||||||
|
struct task_struct *oldowner = pi_state->owner;
|
||||||
u32 uval, curval, newval;
|
u32 uval, curval, newval;
|
||||||
int ret;
|
int ret, attempt = 0;
|
||||||
|
|
||||||
/* Owner died? */
|
/* Owner died? */
|
||||||
|
if (!pi_state->owner)
|
||||||
|
newtid |= FUTEX_OWNER_DIED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are here either because we stole the rtmutex from the
|
||||||
|
* pending owner or we are the pending owner which failed to
|
||||||
|
* get the rtmutex. We have to replace the pending owner TID
|
||||||
|
* in the user space variable. This must be atomic as we have
|
||||||
|
* to preserve the owner died bit here.
|
||||||
|
*
|
||||||
|
* Note: We write the user space value _before_ changing the
|
||||||
|
* pi_state because we can fault here. Imagine swapped out
|
||||||
|
* pages or a fork, which was running right before we acquired
|
||||||
|
* mmap_sem, that marked all the anonymous memory readonly for
|
||||||
|
* cow.
|
||||||
|
*
|
||||||
|
* Modifying pi_state _before_ the user space value would
|
||||||
|
* leave the pi_state in an inconsistent state when we fault
|
||||||
|
* here, because we need to drop the hash bucket lock to
|
||||||
|
* handle the fault. This might be observed in the PID check
|
||||||
|
* in lookup_pi_state.
|
||||||
|
*/
|
||||||
|
retry:
|
||||||
|
if (get_futex_value_locked(&uval, uaddr))
|
||||||
|
goto handle_fault;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
newval = (uval & FUTEX_OWNER_DIED) | newtid;
|
||||||
|
|
||||||
|
curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
|
||||||
|
|
||||||
|
if (curval == -EFAULT)
|
||||||
|
goto handle_fault;
|
||||||
|
if (curval == uval)
|
||||||
|
break;
|
||||||
|
uval = curval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fixed up user space. Now we need to fix the pi_state
|
||||||
|
* itself.
|
||||||
|
*/
|
||||||
if (pi_state->owner != NULL) {
|
if (pi_state->owner != NULL) {
|
||||||
spin_lock_irq(&pi_state->owner->pi_lock);
|
spin_lock_irq(&pi_state->owner->pi_lock);
|
||||||
WARN_ON(list_empty(&pi_state->list));
|
WARN_ON(list_empty(&pi_state->list));
|
||||||
list_del_init(&pi_state->list);
|
list_del_init(&pi_state->list);
|
||||||
spin_unlock_irq(&pi_state->owner->pi_lock);
|
spin_unlock_irq(&pi_state->owner->pi_lock);
|
||||||
} else
|
}
|
||||||
newtid |= FUTEX_OWNER_DIED;
|
|
||||||
|
|
||||||
pi_state->owner = newowner;
|
pi_state->owner = newowner;
|
||||||
|
|
||||||
|
@ -1118,26 +1161,35 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
|
||||||
WARN_ON(!list_empty(&pi_state->list));
|
WARN_ON(!list_empty(&pi_state->list));
|
||||||
list_add(&pi_state->list, &newowner->pi_state_list);
|
list_add(&pi_state->list, &newowner->pi_state_list);
|
||||||
spin_unlock_irq(&newowner->pi_lock);
|
spin_unlock_irq(&newowner->pi_lock);
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We own it, so we have to replace the pending owner
|
* To handle the page fault we need to drop the hash bucket
|
||||||
* TID. This must be atomic as we have preserve the
|
* lock here. That gives the other task (either the pending
|
||||||
* owner died bit here.
|
* owner itself or the task which stole the rtmutex) the
|
||||||
|
* chance to try the fixup of the pi_state. So once we are
|
||||||
|
* back from handling the fault we need to check the pi_state
|
||||||
|
* after reacquiring the hash bucket lock and before trying to
|
||||||
|
* do another fixup. When the fixup has been done already we
|
||||||
|
* simply return.
|
||||||
*/
|
*/
|
||||||
ret = get_futex_value_locked(&uval, uaddr);
|
handle_fault:
|
||||||
|
spin_unlock(q->lock_ptr);
|
||||||
|
|
||||||
while (!ret) {
|
ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++);
|
||||||
newval = (uval & FUTEX_OWNER_DIED) | newtid;
|
|
||||||
|
|
||||||
curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
|
spin_lock(q->lock_ptr);
|
||||||
|
|
||||||
if (curval == -EFAULT)
|
/*
|
||||||
ret = -EFAULT;
|
* Check if someone else fixed it for us:
|
||||||
if (curval == uval)
|
*/
|
||||||
break;
|
if (pi_state->owner != oldowner)
|
||||||
uval = curval;
|
return 0;
|
||||||
}
|
|
||||||
return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1507,7 +1559,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
|
||||||
* that case:
|
* that case:
|
||||||
*/
|
*/
|
||||||
if (q.pi_state->owner != curr)
|
if (q.pi_state->owner != curr)
|
||||||
ret = fixup_pi_state_owner(uaddr, &q, curr);
|
ret = fixup_pi_state_owner(uaddr, &q, curr, fshared);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Catch the rare case, where the lock was released
|
* Catch the rare case, where the lock was released
|
||||||
|
@ -1539,7 +1591,8 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
owner = rt_mutex_owner(&q.pi_state->pi_mutex);
|
owner = rt_mutex_owner(&q.pi_state->pi_mutex);
|
||||||
res = fixup_pi_state_owner(uaddr, &q, owner);
|
res = fixup_pi_state_owner(uaddr, &q, owner,
|
||||||
|
fshared);
|
||||||
|
|
||||||
/* propagate -EFAULT, if the fixup failed */
|
/* propagate -EFAULT, if the fixup failed */
|
||||||
if (res)
|
if (res)
|
||||||
|
|
|
@ -1499,7 +1499,8 @@ int kgdb_nmicallback(int cpu, void *regs)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgdb_console_write(struct console *co, const char *s, unsigned count)
|
static void kgdb_console_write(struct console *co, const char *s,
|
||||||
|
unsigned count)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
|
@ -4398,22 +4398,20 @@ do_wait_for_common(struct completion *x, long timeout, int state)
|
||||||
signal_pending(current)) ||
|
signal_pending(current)) ||
|
||||||
(state == TASK_KILLABLE &&
|
(state == TASK_KILLABLE &&
|
||||||
fatal_signal_pending(current))) {
|
fatal_signal_pending(current))) {
|
||||||
__remove_wait_queue(&x->wait, &wait);
|
timeout = -ERESTARTSYS;
|
||||||
return -ERESTARTSYS;
|
break;
|
||||||
}
|
}
|
||||||
__set_current_state(state);
|
__set_current_state(state);
|
||||||
spin_unlock_irq(&x->wait.lock);
|
spin_unlock_irq(&x->wait.lock);
|
||||||
timeout = schedule_timeout(timeout);
|
timeout = schedule_timeout(timeout);
|
||||||
spin_lock_irq(&x->wait.lock);
|
spin_lock_irq(&x->wait.lock);
|
||||||
if (!timeout) {
|
} while (!x->done && timeout);
|
||||||
__remove_wait_queue(&x->wait, &wait);
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
} while (!x->done);
|
|
||||||
__remove_wait_queue(&x->wait, &wait);
|
__remove_wait_queue(&x->wait, &wait);
|
||||||
|
if (!x->done)
|
||||||
|
return timeout;
|
||||||
}
|
}
|
||||||
x->done--;
|
x->done--;
|
||||||
return timeout;
|
return timeout ?: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long __sched
|
static long __sched
|
||||||
|
|
|
@ -250,7 +250,8 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
|
||||||
if (rt_rq->rt_time || rt_rq->rt_nr_running)
|
if (rt_rq->rt_time || rt_rq->rt_nr_running)
|
||||||
idle = 0;
|
idle = 0;
|
||||||
spin_unlock(&rt_rq->rt_runtime_lock);
|
spin_unlock(&rt_rq->rt_runtime_lock);
|
||||||
}
|
} else if (rt_rq->rt_nr_running)
|
||||||
|
idle = 0;
|
||||||
|
|
||||||
if (enqueue)
|
if (enqueue)
|
||||||
sched_rt_rq_enqueue(rt_rq);
|
sched_rt_rq_enqueue(rt_rq);
|
||||||
|
|
|
@ -442,15 +442,17 @@ unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
|
||||||
return init_bootmem_core(pgdat, freepfn, startpfn, endpfn);
|
return init_bootmem_core(pgdat, freepfn, startpfn, endpfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
|
int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
|
||||||
unsigned long size, int flags)
|
unsigned long size, int flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = can_reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
|
ret = can_reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
return -ENOMEM;
|
||||||
reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
|
reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
|
void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
|
||||||
|
|
50
mm/memory.c
50
mm/memory.c
|
@ -1045,6 +1045,26 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Can we do the FOLL_ANON optimization? */
|
||||||
|
static inline int use_zero_page(struct vm_area_struct *vma)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We don't want to optimize FOLL_ANON for make_pages_present()
|
||||||
|
* when it tries to page in a VM_LOCKED region. As to VM_SHARED,
|
||||||
|
* we want to get the page from the page tables to make sure
|
||||||
|
* that we serialize and update with any other user of that
|
||||||
|
* mapping.
|
||||||
|
*/
|
||||||
|
if (vma->vm_flags & (VM_LOCKED | VM_SHARED))
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
* And if we have a fault or a nopfn routine, it's not an
|
||||||
|
* anonymous region.
|
||||||
|
*/
|
||||||
|
return !vma->vm_ops ||
|
||||||
|
(!vma->vm_ops->fault && !vma->vm_ops->nopfn);
|
||||||
|
}
|
||||||
|
|
||||||
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
|
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
|
||||||
unsigned long start, int len, int write, int force,
|
unsigned long start, int len, int write, int force,
|
||||||
struct page **pages, struct vm_area_struct **vmas)
|
struct page **pages, struct vm_area_struct **vmas)
|
||||||
|
@ -1119,8 +1139,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
|
||||||
foll_flags = FOLL_TOUCH;
|
foll_flags = FOLL_TOUCH;
|
||||||
if (pages)
|
if (pages)
|
||||||
foll_flags |= FOLL_GET;
|
foll_flags |= FOLL_GET;
|
||||||
if (!write && !(vma->vm_flags & VM_LOCKED) &&
|
if (!write && use_zero_page(vma))
|
||||||
(!vma->vm_ops || !vma->vm_ops->fault))
|
|
||||||
foll_flags |= FOLL_ANON;
|
foll_flags |= FOLL_ANON;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -1766,7 +1785,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||||
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
|
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
|
||||||
if (likely(pte_same(*page_table, orig_pte))) {
|
if (likely(pte_same(*page_table, orig_pte))) {
|
||||||
if (old_page) {
|
if (old_page) {
|
||||||
page_remove_rmap(old_page, vma);
|
|
||||||
if (!PageAnon(old_page)) {
|
if (!PageAnon(old_page)) {
|
||||||
dec_mm_counter(mm, file_rss);
|
dec_mm_counter(mm, file_rss);
|
||||||
inc_mm_counter(mm, anon_rss);
|
inc_mm_counter(mm, anon_rss);
|
||||||
|
@ -1788,6 +1806,32 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||||
lru_cache_add_active(new_page);
|
lru_cache_add_active(new_page);
|
||||||
page_add_new_anon_rmap(new_page, vma, address);
|
page_add_new_anon_rmap(new_page, vma, address);
|
||||||
|
|
||||||
|
if (old_page) {
|
||||||
|
/*
|
||||||
|
* Only after switching the pte to the new page may
|
||||||
|
* we remove the mapcount here. Otherwise another
|
||||||
|
* process may come and find the rmap count decremented
|
||||||
|
* before the pte is switched to the new page, and
|
||||||
|
* "reuse" the old page writing into it while our pte
|
||||||
|
* here still points into it and can be read by other
|
||||||
|
* threads.
|
||||||
|
*
|
||||||
|
* The critical issue is to order this
|
||||||
|
* page_remove_rmap with the ptp_clear_flush above.
|
||||||
|
* Those stores are ordered by (if nothing else,)
|
||||||
|
* the barrier present in the atomic_add_negative
|
||||||
|
* in page_remove_rmap.
|
||||||
|
*
|
||||||
|
* Then the TLB flush in ptep_clear_flush ensures that
|
||||||
|
* no process can access the old page before the
|
||||||
|
* decremented mapcount is visible. And the old page
|
||||||
|
* cannot be reused until after the decremented
|
||||||
|
* mapcount is visible. So transitively, TLBs to
|
||||||
|
* old page will be flushed before it can be reused.
|
||||||
|
*/
|
||||||
|
page_remove_rmap(old_page, vma);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the old page.. */
|
/* Free the old page.. */
|
||||||
new_page = old_page;
|
new_page = old_page;
|
||||||
ret |= VM_FAULT_WRITE;
|
ret |= VM_FAULT_WRITE;
|
||||||
|
|
|
@ -3263,9 +3263,12 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
|
||||||
|
|
||||||
if (cpuset_zone_allowed_hardwall(zone, flags) &&
|
if (cpuset_zone_allowed_hardwall(zone, flags) &&
|
||||||
cache->nodelists[nid] &&
|
cache->nodelists[nid] &&
|
||||||
cache->nodelists[nid]->free_objects)
|
cache->nodelists[nid]->free_objects) {
|
||||||
obj = ____cache_alloc_node(cache,
|
obj = ____cache_alloc_node(cache,
|
||||||
flags | GFP_THISNODE, nid);
|
flags | GFP_THISNODE, nid);
|
||||||
|
if (obj)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
|
|
@ -2077,6 +2077,10 @@ int netif_receive_skb(struct sk_buff *skb)
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
|
/* Don't receive packets in an exiting network namespace */
|
||||||
|
if (!net_alive(dev_net(skb->dev)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
if (skb->tc_verd & TC_NCLS) {
|
if (skb->tc_verd & TC_NCLS) {
|
||||||
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
|
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
|
||||||
|
|
|
@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work)
|
||||||
struct pernet_operations *ops;
|
struct pernet_operations *ops;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
|
/* Be very certain incoming network packets will not find us */
|
||||||
|
rcu_barrier();
|
||||||
|
|
||||||
net = container_of(work, struct net, work);
|
net = container_of(work, struct net, work);
|
||||||
|
|
||||||
mutex_lock(&net_mutex);
|
mutex_lock(&net_mutex);
|
||||||
|
|
|
@ -102,6 +102,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
|
||||||
if (hdr->version != 6)
|
if (hdr->version != 6)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC4291 2.5.3
|
||||||
|
* A packet received on an interface with a destination address
|
||||||
|
* of loopback must be dropped.
|
||||||
|
*/
|
||||||
|
if (!(dev->flags & IFF_LOOPBACK) &&
|
||||||
|
ipv6_addr_loopback(&hdr->daddr))
|
||||||
|
goto err;
|
||||||
|
|
||||||
skb->transport_header = skb->network_header + sizeof(*hdr);
|
skb->transport_header = skb->network_header + sizeof(*hdr);
|
||||||
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
|
||||||
|
|
||||||
|
|
|
@ -345,18 +345,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
case IPV6_DSTOPTS:
|
case IPV6_DSTOPTS:
|
||||||
{
|
{
|
||||||
struct ipv6_txoptions *opt;
|
struct ipv6_txoptions *opt;
|
||||||
|
|
||||||
|
/* remove any sticky options header with a zero option
|
||||||
|
* length, per RFC3542.
|
||||||
|
*/
|
||||||
if (optlen == 0)
|
if (optlen == 0)
|
||||||
optval = NULL;
|
optval = NULL;
|
||||||
|
else if (optlen < sizeof(struct ipv6_opt_hdr) ||
|
||||||
|
optlen & 0x7 || optlen > 8 * 255)
|
||||||
|
goto e_inval;
|
||||||
|
|
||||||
/* hop-by-hop / destination options are privileged option */
|
/* hop-by-hop / destination options are privileged option */
|
||||||
retv = -EPERM;
|
retv = -EPERM;
|
||||||
if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
|
if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (optlen < sizeof(struct ipv6_opt_hdr) ||
|
|
||||||
optlen & 0x7 || optlen > 8 * 255)
|
|
||||||
goto e_inval;
|
|
||||||
|
|
||||||
opt = ipv6_renew_options(sk, np->opt, optname,
|
opt = ipv6_renew_options(sk, np->opt, optname,
|
||||||
(struct ipv6_opt_hdr __user *)optval,
|
(struct ipv6_opt_hdr __user *)optval,
|
||||||
optlen);
|
optlen);
|
||||||
|
|
|
@ -1132,7 +1132,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
|
||||||
ieee80211_tx_handler *handler;
|
ieee80211_tx_handler *handler;
|
||||||
struct ieee80211_tx_data tx;
|
struct ieee80211_tx_data tx;
|
||||||
ieee80211_tx_result res = TX_DROP, res_prepare;
|
ieee80211_tx_result res = TX_DROP, res_prepare;
|
||||||
int ret, i;
|
int ret, i, retries = 0;
|
||||||
|
|
||||||
WARN_ON(__ieee80211_queue_pending(local, control->queue));
|
WARN_ON(__ieee80211_queue_pending(local, control->queue));
|
||||||
|
|
||||||
|
@ -1216,6 +1216,13 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
|
||||||
if (!__ieee80211_queue_stopped(local, control->queue)) {
|
if (!__ieee80211_queue_stopped(local, control->queue)) {
|
||||||
clear_bit(IEEE80211_LINK_STATE_PENDING,
|
clear_bit(IEEE80211_LINK_STATE_PENDING,
|
||||||
&local->state[control->queue]);
|
&local->state[control->queue]);
|
||||||
|
retries++;
|
||||||
|
/*
|
||||||
|
* Driver bug, it's rejecting packets but
|
||||||
|
* not stopping queues.
|
||||||
|
*/
|
||||||
|
if (WARN_ON_ONCE(retries > 5))
|
||||||
|
goto drop;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
memcpy(&store->control, control,
|
memcpy(&store->control, control,
|
||||||
|
|
|
@ -4401,7 +4401,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
|
||||||
if (copy_from_user(&getaddrs, optval, len))
|
if (copy_from_user(&getaddrs, optval, len))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (getaddrs.addr_num <= 0) return -EINVAL;
|
if (getaddrs.addr_num <= 0 ||
|
||||||
|
getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr)))
|
||||||
|
return -EINVAL;
|
||||||
/*
|
/*
|
||||||
* For UDP-style sockets, id specifies the association to query.
|
* For UDP-style sockets, id specifies the association to query.
|
||||||
* If the id field is set to the value '0' then the locally bound
|
* If the id field is set to the value '0' then the locally bound
|
||||||
|
|
|
@ -925,7 +925,7 @@ static unsigned char als4000_saved_regs[] = {
|
||||||
static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
||||||
{
|
{
|
||||||
unsigned char *val = chip->saved_regs;
|
unsigned char *val = chip->saved_regs;
|
||||||
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
|
snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
|
||||||
for (; num_regs; num_regs--)
|
for (; num_regs; num_regs--)
|
||||||
*val++ = snd_sbmixer_read(chip, *regs++);
|
*val++ = snd_sbmixer_read(chip, *regs++);
|
||||||
}
|
}
|
||||||
|
@ -933,7 +933,7 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
||||||
static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
||||||
{
|
{
|
||||||
unsigned char *val = chip->saved_regs;
|
unsigned char *val = chip->saved_regs;
|
||||||
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
|
snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
|
||||||
for (; num_regs; num_regs--)
|
for (; num_regs; num_regs--)
|
||||||
snd_sbmixer_write(chip, *regs++, *val++);
|
snd_sbmixer_write(chip, *regs++, *val++);
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,6 +316,8 @@ static int __devinit snd_aw2_create(struct snd_card *card,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (2) initialization of the chip hardware */
|
||||||
|
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
|
||||||
|
|
||||||
if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
|
if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
|
||||||
IRQF_SHARED, "Audiowerk2", chip)) {
|
IRQF_SHARED, "Audiowerk2", chip)) {
|
||||||
|
@ -329,8 +331,6 @@ static int __devinit snd_aw2_create(struct snd_card *card,
|
||||||
}
|
}
|
||||||
chip->irq = pci->irq;
|
chip->irq = pci->irq;
|
||||||
|
|
||||||
/* (2) initialization of the chip hardware */
|
|
||||||
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
|
|
||||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
free_irq(chip->irq, (void *)chip);
|
free_irq(chip->irq, (void *)chip);
|
||||||
|
|
|
@ -269,28 +269,9 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector)
|
static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < IOAPIC_NUM_PINS; i++)
|
|
||||||
if (ioapic->redirtbl[i].fields.vector == vector)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
|
|
||||||
{
|
|
||||||
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
|
|
||||||
union ioapic_redir_entry *ent;
|
union ioapic_redir_entry *ent;
|
||||||
int gsi;
|
|
||||||
|
|
||||||
gsi = get_eoi_gsi(ioapic, vector);
|
|
||||||
if (gsi == -1) {
|
|
||||||
printk(KERN_WARNING "Can't find redir item for %d EOI\n",
|
|
||||||
vector);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = &ioapic->redirtbl[gsi];
|
ent = &ioapic->redirtbl[gsi];
|
||||||
ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
|
ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
|
||||||
|
@ -300,6 +281,16 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
|
||||||
ioapic_deliver(ioapic, gsi);
|
ioapic_deliver(ioapic, gsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
|
||||||
|
{
|
||||||
|
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < IOAPIC_NUM_PINS; i++)
|
||||||
|
if (ioapic->redirtbl[i].fields.vector == vector)
|
||||||
|
__kvm_ioapic_update_eoi(ioapic, i);
|
||||||
|
}
|
||||||
|
|
||||||
static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
|
static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
|
||||||
{
|
{
|
||||||
struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
|
struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
|
||||||
|
|
Loading…
Reference in New Issue