Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
9a131501
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
9a131501
编写于
6月 26, 2008
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge commit 'v2.6.26-rc8' into core/rcu
上级
3ccf79f4
543cf4cb
变更
49
显示空白变更内容
内联
并排
Showing
49 changed file
with
646 addition
and
499 deletion
+646
-499
Documentation/DocBook/kgdb.tmpl
Documentation/DocBook/kgdb.tmpl
+6
-14
Makefile
Makefile
+1
-1
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/iosapic.c
+0
-2
arch/ia64/kernel/setup.c
arch/ia64/kernel/setup.c
+1
-2
arch/ia64/sn/kernel/sn2/sn2_smp.c
arch/ia64/sn/kernel/sn2/sn2_smp.c
+1
-1
arch/x86/Kconfig
arch/x86/Kconfig
+5
-0
arch/x86/kernel/Makefile
arch/x86/kernel/Makefile
+1
-0
arch/x86/kernel/kvmclock.c
arch/x86/kernel/kvmclock.c
+33
-56
arch/x86/kernel/pvclock.c
arch/x86/kernel/pvclock.c
+141
-0
arch/x86/kvm/i8254.c
arch/x86/kvm/i8254.c
+6
-3
arch/x86/kvm/lapic.c
arch/x86/kvm/lapic.c
+1
-0
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.c
+8
-11
arch/x86/kvm/vmx.c
arch/x86/kvm/vmx.c
+11
-8
arch/x86/kvm/x86.c
arch/x86/kvm/x86.c
+66
-25
arch/x86/xen/Kconfig
arch/x86/xen/Kconfig
+2
-1
arch/x86/xen/enlighten.c
arch/x86/xen/enlighten.c
+23
-33
arch/x86/xen/mmu.c
arch/x86/xen/mmu.c
+32
-43
arch/x86/xen/mmu.h
arch/x86/xen/mmu.h
+6
-18
arch/x86/xen/time.c
arch/x86/xen/time.c
+12
-120
arch/x86/xen/xen-head.S
arch/x86/xen/xen-head.S
+1
-5
drivers/char/drm/i915_drv.c
drivers/char/drm/i915_drv.c
+1
-0
drivers/char/tty_ioctl.c
drivers/char/tty_ioctl.c
+0
-7
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/infiniband/hw/mthca/mthca_memfree.c
+5
-1
drivers/lguest/x86/core.c
drivers/lguest/x86/core.c
+9
-6
drivers/watchdog/Makefile
drivers/watchdog/Makefile
+0
-1
drivers/xen/events.c
drivers/xen/events.c
+1
-1
fs/gfs2/bmap.c
fs/gfs2/bmap.c
+9
-14
fs/gfs2/rgrp.c
fs/gfs2/rgrp.c
+1
-1
fs/nfs/mount_clnt.c
fs/nfs/mount_clnt.c
+3
-2
fs/nfs/super.c
fs/nfs/super.c
+44
-32
fs/nfs/write.c
fs/nfs/write.c
+4
-3
fs/select.c
fs/select.c
+1
-1
include/asm-alpha/percpu.h
include/asm-alpha/percpu.h
+2
-0
include/asm-x86/kvm_host.h
include/asm-x86/kvm_host.h
+3
-1
include/asm-x86/kvm_para.h
include/asm-x86/kvm_para.h
+0
-18
include/asm-x86/pvclock-abi.h
include/asm-x86/pvclock-abi.h
+42
-0
include/asm-x86/pvclock.h
include/asm-x86/pvclock.h
+13
-0
include/asm-x86/xen/page.h
include/asm-x86/xen/page.h
+0
-4
include/linux/kvm_host.h
include/linux/kvm_host.h
+1
-0
include/linux/tty_driver.h
include/linux/tty_driver.h
+2
-3
include/xen/interface/xen.h
include/xen/interface/xen.h
+3
-4
kernel/futex.c
kernel/futex.c
+73
-20
kernel/kgdb.c
kernel/kgdb.c
+2
-1
kernel/sched.c
kernel/sched.c
+6
-8
kernel/sched_rt.c
kernel/sched_rt.c
+2
-1
mm/memory.c
mm/memory.c
+47
-3
sound/isa/sb/sb_mixer.c
sound/isa/sb/sb_mixer.c
+2
-2
sound/pci/aw2/aw2-alsa.c
sound/pci/aw2/aw2-alsa.c
+2
-2
virt/kvm/ioapic.c
virt/kvm/ioapic.c
+11
-20
未找到文件。
Documentation/DocBook/kgdb.tmpl
浏览文件 @
9a131501
...
@@ -84,10 +84,9 @@
...
@@ -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 @@
...
@@ -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 @@
...
@@ -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
...
...
Makefile
浏览文件 @
9a131501
VERSION
=
2
VERSION
=
2
PATCHLEVEL
=
6
PATCHLEVEL
=
6
SUBLEVEL
=
26
SUBLEVEL
=
26
EXTRAVERSION
=
-rc
7
EXTRAVERSION
=
-rc
8
NAME
=
Rotary Wombat
NAME
=
Rotary Wombat
# *DOCUMENTATION*
# *DOCUMENTATION*
...
...
arch/ia64/kernel/iosapic.c
浏览文件 @
9a131501
...
@@ -558,8 +558,6 @@ static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
...
@@ -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
);
}
}
...
...
arch/ia64/kernel/setup.c
浏览文件 @
9a131501
...
@@ -578,8 +578,6 @@ setup_arch (char **cmdline_p)
...
@@ -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)
...
@@ -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
();
}
}
...
...
arch/ia64/sn/kernel/sn2/sn2_smp.c
浏览文件 @
9a131501
...
@@ -512,7 +512,7 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si
...
@@ -512,7 +512,7 @@ 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
>
sizeof
(
optstr
))
if
(
count
==
0
||
count
>
sizeof
(
optstr
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
copy_from_user
(
optstr
,
user
,
count
))
if
(
copy_from_user
(
optstr
,
user
,
count
))
return
-
EFAULT
;
return
-
EFAULT
;
...
...
arch/x86/Kconfig
浏览文件 @
9a131501
...
@@ -383,6 +383,7 @@ config VMI
...
@@ -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
...
@@ -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
...
...
arch/x86/kernel/Makefile
浏览文件 @
9a131501
...
@@ -82,6 +82,7 @@ obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
...
@@ -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
...
...
arch/x86/kernel/kvmclock.c
浏览文件 @
9a131501
...
@@ -18,6 +18,7 @@
...
@@ -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)
...
@@ -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);
...
@@ -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
);
native_write_msr
(
MSR_KVM_WALL_CLOCK
,
low
,
high
);
delta
=
kvm_clock_read
();
vcpu_time
=
&
get_cpu_var
(
hv_clock
);
pvclock_read_wallclock
(
&
wall_clock
,
vcpu_time
,
&
ts
);
put_cpu_var
(
hv_clock
);
native_write_msr
(
MSR_KVM_WALL_CLOCK
,
low
,
high
);
return
ts
.
tv_sec
;
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
;
delta
+=
wc_nsec
;
nsec
=
do_div
(
delta
,
NSEC_PER_SEC
);
set_normalized_timespec
(
&
ts
,
wc_sec
+
delta
,
nsec
);
/*
* 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 = {
...
@@ -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)
...
@@ -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)
...
@@ -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
...
...
arch/x86/kernel/pvclock.c
0 → 100644
浏览文件 @
9a131501
/* 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
);
}
arch/x86/kvm/i8254.c
浏览文件 @
9a131501
...
@@ -200,10 +200,13 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)
...
@@ -200,10 +200,13 @@ 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
)
{
set_bit
(
KVM_REQ_PENDING_TIMER
,
&
vcpu0
->
requests
);
if
(
waitqueue_active
(
&
vcpu0
->
wq
))
{
vcpu0
->
arch
.
mp_state
=
KVM_MP_STATE_RUNNABLE
;
vcpu0
->
arch
.
mp_state
=
KVM_MP_STATE_RUNNABLE
;
wake_up_interruptible
(
&
vcpu0
->
wq
);
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
);
pt
->
scheduled
=
ktime_to_ns
(
pt
->
timer
.
expires
);
pt
->
scheduled
=
ktime_to_ns
(
pt
->
timer
.
expires
);
...
...
arch/x86/kvm/lapic.c
浏览文件 @
9a131501
...
@@ -940,6 +940,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
...
@@ -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
);
...
...
arch/x86/kvm/mmu.c
浏览文件 @
9a131501
...
@@ -640,6 +640,7 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn)
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
||
sp
->
role
.
glevels
==
PT32_ROOT_LEVEL
)
{
++
vcpu
->
kvm
->
stat
.
mmu_pde_zapped
;
++
vcpu
->
kvm
->
stat
.
mmu_pde_zapped
;
return
;
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
)
...
...
arch/x86/kvm/vmx.c
浏览文件 @
9a131501
...
@@ -566,7 +566,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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
);
...
...
arch/x86/kvm/x86.c
浏览文件 @
9a131501
...
@@ -492,8 +492,8 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *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)
...
@@ -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)
...
@@ -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)
...
@@ -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,9 +590,9 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
...
@@ -537,9 +590,9 @@ 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
);
...
@@ -599,10 +652,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
...
@@ -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
(
&
current
->
mm
->
mmap_sem
);
down_read
(
&
current
->
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)
...
@@ -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)
...
@@ -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,15 +2833,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
...
@@ -2781,15 +2833,7 @@ 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
();
preempt_enable
();
r
=
1
;
goto
out
;
}
if
(
vcpu
->
requests
)
if
(
test_bit
(
KVM_REQ_MMU_RELOAD
,
&
vcpu
->
requests
))
{
local_irq_enable
();
local_irq_enable
();
preempt_enable
();
preempt_enable
();
r
=
1
;
r
=
1
;
...
@@ -2825,9 +2869,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
...
@@ -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
);
...
...
arch/x86/xen/Kconfig
浏览文件 @
9a131501
...
@@ -5,8 +5,9 @@
...
@@ -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
...
...
arch/x86/xen/enlighten.c
浏览文件 @
9a131501
...
@@ -785,20 +785,18 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
...
@@ -785,20 +785,18 @@ 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
* For PAE, need to allocate new pmds, rather than
* share Xen's, since Xen doesn't like pmd's being
* share Xen's, since Xen doesn't like pmd's being
...
@@ -817,7 +815,6 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
...
@@ -817,7 +815,6 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
}
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 */
make_lowmem_page_readonly
(
empty_zero_page
);
make_lowmem_page_readonly
(
empty_zero_page
);
...
@@ -873,17 +870,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
...
@@ -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 = {
...
@@ -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 = {
...
@@ -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)
...
@@ -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
();
...
...
arch/x86/xen/mmu.c
浏览文件 @
9a131501
...
@@ -179,50 +179,56 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
...
@@ -179,50 +179,56 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
preempt_enable
();
preempt_enable
();
}
}
pteval_t
xen_pte_val
(
pte_t
pte
)
/* 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
)
{
{
pteval_t
ret
=
pte
.
pte
;
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
;
}
if
(
ret
&
_PAGE_PRESENT
)
return
val
;
ret
=
machine_to_phys
(
XMADDR
(
ret
)).
paddr
|
_PAGE_PRESENT
;
}
return
ret
;
pteval_t
xen_pte_val
(
pte_t
pte
)
{
return
pte_mfn_to_pfn
(
pte
.
pte
);
}
}
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)
...
@@ -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)
...
@@ -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)
...
@@ -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
);
}
}
...
...
arch/x86/xen/mmu.h
浏览文件 @
9a131501
...
@@ -37,14 +37,13 @@ void xen_exit_mmap(struct mm_struct *mm);
...
@@ -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);
...
@@ -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 */
arch/x86/xen/time.c
浏览文件 @
9a131501
...
@@ -14,6 +14,7 @@
...
@@ -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 @@
...
@@ -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)
...
@@ -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)
...
@@ -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 */
do
{
version
=
s
->
wc_version
;
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 */
vcpu_time
=
&
get_cpu_var
(
xen_vcpu
)
->
time
;
delta
+=
now
.
tv_sec
*
(
u64
)
NSEC_PER_SEC
+
now
.
tv_nsec
;
pvclock_read_wallclock
(
wall_clock
,
vcpu_time
,
ts
);
put_cpu_var
(
xen_vcpu
);
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)
...
@@ -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)
...
@@ -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
)
{
...
...
arch/x86/xen/xen-head.S
浏览文件 @
9a131501
...
@@ -17,7 +17,7 @@ ENTRY(startup_xen)
...
@@ -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)
...
@@ -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 */
drivers/char/drm/i915_drv.c
浏览文件 @
9a131501
...
@@ -389,6 +389,7 @@ static int i915_resume(struct drm_device *dev)
...
@@ -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
);
...
...
drivers/char/tty_ioctl.c
浏览文件 @
9a131501
...
@@ -981,16 +981,9 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
...
@@ -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
);
...
...
drivers/infiniband/hw/mthca/mthca_memfree.c
浏览文件 @
9a131501
...
@@ -109,7 +109,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
...
@@ -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
;
...
...
drivers/lguest/x86/core.c
浏览文件 @
9a131501
...
@@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
...
@@ -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)
...
@@ -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)
...
@@ -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.
...
...
drivers/watchdog/Makefile
浏览文件 @
9a131501
...
@@ -68,7 +68,6 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
...
@@ -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
...
...
drivers/xen/events.c
浏览文件 @
9a131501
...
@@ -529,7 +529,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
...
@@ -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. */
r
mb
();
w
mb
();
#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
)
{
...
...
fs/gfs2/bmap.c
浏览文件 @
9a131501
...
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
;
...
...
fs/gfs2/rgrp.c
浏览文件 @
9a131501
...
@@ -195,7 +195,7 @@ static u32 gfs2_bitfit(const u8 *buffer, unsigned int buflen, u32 goal,
...
@@ -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
;
...
...
fs/nfs/mount_clnt.c
浏览文件 @
9a131501
...
@@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
...
@@ -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
...
...
fs/nfs/super.c
浏览文件 @
9a131501
...
@@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options,
...
@@ -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,
...
@@ -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,
...
@@ -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
;
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
);
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,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
;
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
);
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,
...
@@ -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,
...
@@ -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:
...
...
fs/nfs/write.c
浏览文件 @
9a131501
...
@@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page,
...
@@ -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
);
if
(
status
<
0
)
nfs_set_pageerror
(
page
);
else
__set_page_dirty_nobuffers
(
page
);
__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
;
}
}
...
...
fs/select.c
浏览文件 @
9a131501
...
@@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
...
@@ -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)
...
@@ -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
))
...
...
include/asm-alpha/percpu.h
浏览文件 @
9a131501
...
@@ -69,6 +69,8 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
...
@@ -69,6 +69,8 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
#define __get_cpu_var(var) per_cpu_var(var)
#define __get_cpu_var(var) per_cpu_var(var)
#define __raw_get_cpu_var(var) per_cpu_var(var)
#define __raw_get_cpu_var(var) per_cpu_var(var)
#define PER_CPU_ATTRIBUTES
#endif
/* SMP */
#endif
/* SMP */
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
...
...
include/asm-x86/kvm_host.h
浏览文件 @
9a131501
...
@@ -18,6 +18,7 @@
...
@@ -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 {
...
@@ -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
;
};
};
...
...
include/asm-x86/kvm_para.h
浏览文件 @
9a131501
...
@@ -48,24 +48,6 @@ struct kvm_mmu_op_release_pt {
...
@@ -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
);
...
...
include/asm-x86/pvclock-abi.h
0 → 100644
浏览文件 @
9a131501
#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_ */
include/asm-x86/pvclock.h
0 → 100644
浏览文件 @
9a131501
#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_ */
include/asm-x86/xen/page.h
浏览文件 @
9a131501
...
@@ -150,13 +150,9 @@ static inline pte_t __pte_ma(pteval_t x)
...
@@ -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)
...
...
include/linux/kvm_host.h
浏览文件 @
9a131501
...
@@ -33,6 +33,7 @@
...
@@ -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
;
...
...
include/linux/tty_driver.h
浏览文件 @
9a131501
...
@@ -27,8 +27,7 @@
...
@@ -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 @@
...
@@ -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);
*
*
...
...
include/xen/interface/xen.h
浏览文件 @
9a131501
...
@@ -10,6 +10,7 @@
...
@@ -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 {
...
@@ -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 {
...
@@ -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
;
...
...
kernel/futex.c
浏览文件 @
9a131501
...
@@ -1096,21 +1096,64 @@ static void unqueue_me_pi(struct futex_q *q)
...
@@ -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,
...
@@ -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
;
}
if
(
ret
)
return
ret
;
return
ret
;
goto
retry
;
}
}
/*
/*
...
@@ -1507,7 +1559,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
...
@@ -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,
...
@@ -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
)
...
...
kernel/kgdb.c
浏览文件 @
9a131501
...
@@ -1499,7 +1499,8 @@ int kgdb_nmicallback(int cpu, void *regs)
...
@@ -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
;
...
...
kernel/sched.c
浏览文件 @
9a131501
...
@@ -4398,22 +4398,20 @@ do_wait_for_common(struct completion *x, long timeout, int state)
...
@@ -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
);
__remove_wait_queue
(
&
x
->
wait
,
&
wait
);
if
(
!
x
->
done
)
return
timeout
;
return
timeout
;
}
}
}
while
(
!
x
->
done
);
__remove_wait_queue
(
&
x
->
wait
,
&
wait
);
}
x
->
done
--
;
x
->
done
--
;
return
timeout
;
return
timeout
?:
1
;
}
}
static
long
__sched
static
long
__sched
...
...
kernel/sched_rt.c
浏览文件 @
9a131501
...
@@ -250,7 +250,8 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
...
@@ -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
);
...
...
mm/memory.c
浏览文件 @
9a131501
...
@@ -1045,6 +1045,26 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
;
...
...
sound/isa/sb/sb_mixer.c
浏览文件 @
9a131501
...
@@ -925,7 +925,7 @@ static unsigned char als4000_saved_regs[] = {
...
@@ -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)
...
@@ -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
++
);
}
}
...
...
sound/pci/aw2/aw2-alsa.c
浏览文件 @
9a131501
...
@@ -316,6 +316,8 @@ static int __devinit snd_aw2_create(struct snd_card *card,
...
@@ -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,
...
@@ -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
);
...
...
virt/kvm/ioapic.c
浏览文件 @
9a131501
...
@@ -269,28 +269,9 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
...
@@ -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)
...
@@ -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
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录