Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e93f8a0f
Commit
e93f8a0f
authored
Dec 23, 2009
by
Marcelo Tosatti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
KVM: convert io_bus to SRCU
Signed-off-by:
Marcelo Tosatti
<
mtosatti@redhat.com
>
parent
a983fb23
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
101 additions
and
75 deletions
+101
-75
arch/ia64/kvm/kvm-ia64.c
arch/ia64/kvm/kvm-ia64.c
+2
-2
arch/x86/kvm/i8254.c
arch/x86/kvm/i8254.c
+3
-3
arch/x86/kvm/i8259.c
arch/x86/kvm/i8259.c
+3
-1
arch/x86/kvm/x86.c
arch/x86/kvm/x86.c
+7
-6
include/linux/kvm_host.h
include/linux/kvm_host.h
+13
-14
virt/kvm/coalesced_mmio.c
virt/kvm/coalesced_mmio.c
+3
-1
virt/kvm/eventfd.c
virt/kvm/eventfd.c
+4
-4
virt/kvm/ioapic.c
virt/kvm/ioapic.c
+3
-1
virt/kvm/kvm_main.c
virt/kvm/kvm_main.c
+63
-43
No files found.
arch/ia64/kvm/kvm-ia64.c
View file @
e93f8a0f
...
@@ -241,10 +241,10 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
...
@@ -241,10 +241,10 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return
0
;
return
0
;
mmio:
mmio:
if
(
p
->
dir
)
if
(
p
->
dir
)
r
=
kvm_io_bus_read
(
&
vcpu
->
kvm
->
mmio_bus
,
p
->
addr
,
r
=
kvm_io_bus_read
(
vcpu
->
kvm
,
KVM_MMIO_BUS
,
p
->
addr
,
p
->
size
,
&
p
->
data
);
p
->
size
,
&
p
->
data
);
else
else
r
=
kvm_io_bus_write
(
&
vcpu
->
kvm
->
mmio_bus
,
p
->
addr
,
r
=
kvm_io_bus_write
(
vcpu
->
kvm
,
KVM_MMIO_BUS
,
p
->
addr
,
p
->
size
,
&
p
->
data
);
p
->
size
,
&
p
->
data
);
if
(
r
)
if
(
r
)
printk
(
KERN_ERR
"kvm: No iodevice found! addr:%lx
\n
"
,
p
->
addr
);
printk
(
KERN_ERR
"kvm: No iodevice found! addr:%lx
\n
"
,
p
->
addr
);
...
...
arch/x86/kvm/i8254.c
View file @
e93f8a0f
...
@@ -645,13 +645,13 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
...
@@ -645,13 +645,13 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
kvm_register_irq_mask_notifier
(
kvm
,
0
,
&
pit
->
mask_notifier
);
kvm_register_irq_mask_notifier
(
kvm
,
0
,
&
pit
->
mask_notifier
);
kvm_iodevice_init
(
&
pit
->
dev
,
&
pit_dev_ops
);
kvm_iodevice_init
(
&
pit
->
dev
,
&
pit_dev_ops
);
ret
=
__kvm_io_bus_register_dev
(
&
kvm
->
pio_bus
,
&
pit
->
dev
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
KVM_PIO_BUS
,
&
pit
->
dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
fail
;
goto
fail
;
if
(
flags
&
KVM_PIT_SPEAKER_DUMMY
)
{
if
(
flags
&
KVM_PIT_SPEAKER_DUMMY
)
{
kvm_iodevice_init
(
&
pit
->
speaker_dev
,
&
speaker_dev_ops
);
kvm_iodevice_init
(
&
pit
->
speaker_dev
,
&
speaker_dev_ops
);
ret
=
__kvm_io_bus_register_dev
(
&
kvm
->
pio_bus
,
ret
=
kvm_io_bus_register_dev
(
kvm
,
KVM_PIO_BUS
,
&
pit
->
speaker_dev
);
&
pit
->
speaker_dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
fail_unregister
;
goto
fail_unregister
;
...
@@ -660,7 +660,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
...
@@ -660,7 +660,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
return
pit
;
return
pit
;
fail_unregister:
fail_unregister:
__kvm_io_bus_unregister_dev
(
&
kvm
->
pio_bus
,
&
pit
->
dev
);
kvm_io_bus_unregister_dev
(
kvm
,
KVM_PIO_BUS
,
&
pit
->
dev
);
fail:
fail:
if
(
pit
->
irq_source_id
>=
0
)
if
(
pit
->
irq_source_id
>=
0
)
...
...
arch/x86/kvm/i8259.c
View file @
e93f8a0f
...
@@ -533,7 +533,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
...
@@ -533,7 +533,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
* Initialize PIO device
* Initialize PIO device
*/
*/
kvm_iodevice_init
(
&
s
->
dev
,
&
picdev_ops
);
kvm_iodevice_init
(
&
s
->
dev
,
&
picdev_ops
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
&
kvm
->
pio_bus
,
&
s
->
dev
);
down_write
(
&
kvm
->
slots_lock
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
KVM_PIO_BUS
,
&
s
->
dev
);
up_write
(
&
kvm
->
slots_lock
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
kfree
(
s
);
kfree
(
s
);
return
NULL
;
return
NULL
;
...
...
arch/x86/kvm/x86.c
View file @
e93f8a0f
...
@@ -2851,7 +2851,7 @@ static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
...
@@ -2851,7 +2851,7 @@ static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
!
kvm_iodevice_write
(
&
vcpu
->
arch
.
apic
->
dev
,
addr
,
len
,
v
))
!
kvm_iodevice_write
(
&
vcpu
->
arch
.
apic
->
dev
,
addr
,
len
,
v
))
return
0
;
return
0
;
return
kvm_io_bus_write
(
&
vcpu
->
kvm
->
mmio_bus
,
addr
,
len
,
v
);
return
kvm_io_bus_write
(
vcpu
->
kvm
,
KVM_MMIO_BUS
,
addr
,
len
,
v
);
}
}
static
int
vcpu_mmio_read
(
struct
kvm_vcpu
*
vcpu
,
gpa_t
addr
,
int
len
,
void
*
v
)
static
int
vcpu_mmio_read
(
struct
kvm_vcpu
*
vcpu
,
gpa_t
addr
,
int
len
,
void
*
v
)
...
@@ -2860,7 +2860,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
...
@@ -2860,7 +2860,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
!
kvm_iodevice_read
(
&
vcpu
->
arch
.
apic
->
dev
,
addr
,
len
,
v
))
!
kvm_iodevice_read
(
&
vcpu
->
arch
.
apic
->
dev
,
addr
,
len
,
v
))
return
0
;
return
0
;
return
kvm_io_bus_read
(
&
vcpu
->
kvm
->
mmio_bus
,
addr
,
len
,
v
);
return
kvm_io_bus_read
(
vcpu
->
kvm
,
KVM_MMIO_BUS
,
addr
,
len
,
v
);
}
}
static
int
kvm_read_guest_virt
(
gva_t
addr
,
void
*
val
,
unsigned
int
bytes
,
static
int
kvm_read_guest_virt
(
gva_t
addr
,
void
*
val
,
unsigned
int
bytes
,
...
@@ -3345,11 +3345,12 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
...
@@ -3345,11 +3345,12 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
int
r
;
int
r
;
if
(
vcpu
->
arch
.
pio
.
in
)
if
(
vcpu
->
arch
.
pio
.
in
)
r
=
kvm_io_bus_read
(
&
vcpu
->
kvm
->
pio_bus
,
vcpu
->
arch
.
pio
.
port
,
r
=
kvm_io_bus_read
(
vcpu
->
kvm
,
KVM_PIO_BUS
,
vcpu
->
arch
.
pio
.
port
,
vcpu
->
arch
.
pio
.
size
,
pd
);
vcpu
->
arch
.
pio
.
size
,
pd
);
else
else
r
=
kvm_io_bus_write
(
&
vcpu
->
kvm
->
pio_bus
,
vcpu
->
arch
.
pio
.
port
,
r
=
kvm_io_bus_write
(
vcpu
->
kvm
,
KVM_PIO_BUS
,
vcpu
->
arch
.
pio
.
size
,
pd
);
vcpu
->
arch
.
pio
.
port
,
vcpu
->
arch
.
pio
.
size
,
pd
);
return
r
;
return
r
;
}
}
...
@@ -3360,7 +3361,7 @@ static int pio_string_write(struct kvm_vcpu *vcpu)
...
@@ -3360,7 +3361,7 @@ static int pio_string_write(struct kvm_vcpu *vcpu)
int
i
,
r
=
0
;
int
i
,
r
=
0
;
for
(
i
=
0
;
i
<
io
->
cur_count
;
i
++
)
{
for
(
i
=
0
;
i
<
io
->
cur_count
;
i
++
)
{
if
(
kvm_io_bus_write
(
&
vcpu
->
kvm
->
pio_bus
,
if
(
kvm_io_bus_write
(
vcpu
->
kvm
,
KVM_PIO_BUS
,
io
->
port
,
io
->
size
,
pd
))
{
io
->
port
,
io
->
size
,
pd
))
{
r
=
-
EOPNOTSUPP
;
r
=
-
EOPNOTSUPP
;
break
;
break
;
...
...
include/linux/kvm_host.h
View file @
e93f8a0f
...
@@ -57,20 +57,20 @@ struct kvm_io_bus {
...
@@ -57,20 +57,20 @@ struct kvm_io_bus {
struct
kvm_io_device
*
devs
[
NR_IOBUS_DEVS
];
struct
kvm_io_device
*
devs
[
NR_IOBUS_DEVS
];
};
};
void
kvm_io_bus_init
(
struct
kvm_io_bus
*
bus
);
enum
kvm_bus
{
void
kvm_io_bus_destroy
(
struct
kvm_io_bus
*
bus
);
KVM_MMIO_BUS
,
int
kvm_io_bus_write
(
struct
kvm_io_bus
*
bus
,
gpa_t
addr
,
int
len
,
KVM_PIO_BUS
,
const
void
*
val
);
KVM_NR_BUSES
int
kvm_io_bus_read
(
struct
kvm_io_bus
*
bus
,
gpa_t
addr
,
int
len
,
};
int
kvm_io_bus_write
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
gpa_t
addr
,
int
len
,
const
void
*
val
);
int
kvm_io_bus_read
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
gpa_t
addr
,
int
len
,
void
*
val
);
void
*
val
);
int
__kvm_io_bus_register_dev
(
struct
kvm_io_bus
*
bus
,
int
kvm_io_bus_register_dev
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
struct
kvm_io_device
*
dev
);
int
kvm_io_bus_register_dev
(
struct
kvm
*
kvm
,
struct
kvm_io_bus
*
bus
,
struct
kvm_io_device
*
dev
);
struct
kvm_io_device
*
dev
);
void
__kvm_io_bus_unregister_dev
(
struct
kvm_io_bus
*
bus
,
int
kvm_io_bus_unregister_dev
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
struct
kvm_io_device
*
dev
);
struct
kvm_io_device
*
dev
);
void
kvm_io_bus_unregister_dev
(
struct
kvm
*
kvm
,
struct
kvm_io_bus
*
bus
,
struct
kvm_io_device
*
dev
);
struct
kvm_vcpu
{
struct
kvm_vcpu
{
struct
kvm
*
kvm
;
struct
kvm
*
kvm
;
...
@@ -171,8 +171,7 @@ struct kvm {
...
@@ -171,8 +171,7 @@ struct kvm {
atomic_t
online_vcpus
;
atomic_t
online_vcpus
;
struct
list_head
vm_list
;
struct
list_head
vm_list
;
struct
mutex
lock
;
struct
mutex
lock
;
struct
kvm_io_bus
mmio_bus
;
struct
kvm_io_bus
*
buses
[
KVM_NR_BUSES
];
struct
kvm_io_bus
pio_bus
;
#ifdef CONFIG_HAVE_KVM_EVENTFD
#ifdef CONFIG_HAVE_KVM_EVENTFD
struct
{
struct
{
spinlock_t
lock
;
spinlock_t
lock
;
...
...
virt/kvm/coalesced_mmio.c
View file @
e93f8a0f
...
@@ -110,7 +110,9 @@ int kvm_coalesced_mmio_init(struct kvm *kvm)
...
@@ -110,7 +110,9 @@ int kvm_coalesced_mmio_init(struct kvm *kvm)
dev
->
kvm
=
kvm
;
dev
->
kvm
=
kvm
;
kvm
->
coalesced_mmio_dev
=
dev
;
kvm
->
coalesced_mmio_dev
=
dev
;
ret
=
kvm_io_bus_register_dev
(
kvm
,
&
kvm
->
mmio_bus
,
&
dev
->
dev
);
down_write
(
&
kvm
->
slots_lock
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
KVM_MMIO_BUS
,
&
dev
->
dev
);
up_write
(
&
kvm
->
slots_lock
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out_free_dev
;
goto
out_free_dev
;
...
...
virt/kvm/eventfd.c
View file @
e93f8a0f
...
@@ -463,7 +463,7 @@ static int
...
@@ -463,7 +463,7 @@ static int
kvm_assign_ioeventfd
(
struct
kvm
*
kvm
,
struct
kvm_ioeventfd
*
args
)
kvm_assign_ioeventfd
(
struct
kvm
*
kvm
,
struct
kvm_ioeventfd
*
args
)
{
{
int
pio
=
args
->
flags
&
KVM_IOEVENTFD_FLAG_PIO
;
int
pio
=
args
->
flags
&
KVM_IOEVENTFD_FLAG_PIO
;
struct
kvm_io_bus
*
bus
=
pio
?
&
kvm
->
pio_bus
:
&
kvm
->
mmio_bus
;
enum
kvm_bus
bus_idx
=
pio
?
KVM_PIO_BUS
:
KVM_MMIO_BUS
;
struct
_ioeventfd
*
p
;
struct
_ioeventfd
*
p
;
struct
eventfd_ctx
*
eventfd
;
struct
eventfd_ctx
*
eventfd
;
int
ret
;
int
ret
;
...
@@ -518,7 +518,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
...
@@ -518,7 +518,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
kvm_iodevice_init
(
&
p
->
dev
,
&
ioeventfd_ops
);
kvm_iodevice_init
(
&
p
->
dev
,
&
ioeventfd_ops
);
ret
=
__kvm_io_bus_register_dev
(
bus
,
&
p
->
dev
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
bus_idx
,
&
p
->
dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
unlock_fail
;
goto
unlock_fail
;
...
@@ -542,7 +542,7 @@ static int
...
@@ -542,7 +542,7 @@ static int
kvm_deassign_ioeventfd
(
struct
kvm
*
kvm
,
struct
kvm_ioeventfd
*
args
)
kvm_deassign_ioeventfd
(
struct
kvm
*
kvm
,
struct
kvm_ioeventfd
*
args
)
{
{
int
pio
=
args
->
flags
&
KVM_IOEVENTFD_FLAG_PIO
;
int
pio
=
args
->
flags
&
KVM_IOEVENTFD_FLAG_PIO
;
struct
kvm_io_bus
*
bus
=
pio
?
&
kvm
->
pio_bus
:
&
kvm
->
mmio_bus
;
enum
kvm_bus
bus_idx
=
pio
?
KVM_PIO_BUS
:
KVM_MMIO_BUS
;
struct
_ioeventfd
*
p
,
*
tmp
;
struct
_ioeventfd
*
p
,
*
tmp
;
struct
eventfd_ctx
*
eventfd
;
struct
eventfd_ctx
*
eventfd
;
int
ret
=
-
ENOENT
;
int
ret
=
-
ENOENT
;
...
@@ -565,7 +565,7 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
...
@@ -565,7 +565,7 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
if
(
!
p
->
wildcard
&&
p
->
datamatch
!=
args
->
datamatch
)
if
(
!
p
->
wildcard
&&
p
->
datamatch
!=
args
->
datamatch
)
continue
;
continue
;
__kvm_io_bus_unregister_dev
(
bus
,
&
p
->
dev
);
kvm_io_bus_unregister_dev
(
kvm
,
bus_idx
,
&
p
->
dev
);
ioeventfd_release
(
p
);
ioeventfd_release
(
p
);
ret
=
0
;
ret
=
0
;
break
;
break
;
...
...
virt/kvm/ioapic.c
View file @
e93f8a0f
...
@@ -372,7 +372,9 @@ int kvm_ioapic_init(struct kvm *kvm)
...
@@ -372,7 +372,9 @@ int kvm_ioapic_init(struct kvm *kvm)
kvm_ioapic_reset
(
ioapic
);
kvm_ioapic_reset
(
ioapic
);
kvm_iodevice_init
(
&
ioapic
->
dev
,
&
ioapic_mmio_ops
);
kvm_iodevice_init
(
&
ioapic
->
dev
,
&
ioapic_mmio_ops
);
ioapic
->
kvm
=
kvm
;
ioapic
->
kvm
=
kvm
;
ret
=
kvm_io_bus_register_dev
(
kvm
,
&
kvm
->
mmio_bus
,
&
ioapic
->
dev
);
down_write
(
&
kvm
->
slots_lock
);
ret
=
kvm_io_bus_register_dev
(
kvm
,
KVM_MMIO_BUS
,
&
ioapic
->
dev
);
up_write
(
&
kvm
->
slots_lock
);
if
(
ret
<
0
)
if
(
ret
<
0
)
kfree
(
ioapic
);
kfree
(
ioapic
);
...
...
virt/kvm/kvm_main.c
View file @
e93f8a0f
...
@@ -85,6 +85,8 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
...
@@ -85,6 +85,8 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
static
int
hardware_enable_all
(
void
);
static
int
hardware_enable_all
(
void
);
static
void
hardware_disable_all
(
void
);
static
void
hardware_disable_all
(
void
);
static
void
kvm_io_bus_destroy
(
struct
kvm_io_bus
*
bus
);
static
bool
kvm_rebooting
;
static
bool
kvm_rebooting
;
static
bool
largepages_enabled
=
true
;
static
bool
largepages_enabled
=
true
;
...
@@ -367,7 +369,7 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
...
@@ -367,7 +369,7 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
static
struct
kvm
*
kvm_create_vm
(
void
)
static
struct
kvm
*
kvm_create_vm
(
void
)
{
{
int
r
=
0
;
int
r
=
0
,
i
;
struct
kvm
*
kvm
=
kvm_arch_create_vm
();
struct
kvm
*
kvm
=
kvm_arch_create_vm
();
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
struct
page
*
page
;
struct
page
*
page
;
...
@@ -391,6 +393,14 @@ static struct kvm *kvm_create_vm(void)
...
@@ -391,6 +393,14 @@ static struct kvm *kvm_create_vm(void)
goto
out_err
;
goto
out_err
;
if
(
init_srcu_struct
(
&
kvm
->
srcu
))
if
(
init_srcu_struct
(
&
kvm
->
srcu
))
goto
out_err
;
goto
out_err
;
for
(
i
=
0
;
i
<
KVM_NR_BUSES
;
i
++
)
{
kvm
->
buses
[
i
]
=
kzalloc
(
sizeof
(
struct
kvm_io_bus
),
GFP_KERNEL
);
if
(
!
kvm
->
buses
[
i
])
{
cleanup_srcu_struct
(
&
kvm
->
srcu
);
goto
out_err
;
}
}
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
page
=
alloc_page
(
GFP_KERNEL
|
__GFP_ZERO
);
page
=
alloc_page
(
GFP_KERNEL
|
__GFP_ZERO
);
...
@@ -416,11 +426,9 @@ static struct kvm *kvm_create_vm(void)
...
@@ -416,11 +426,9 @@ static struct kvm *kvm_create_vm(void)
atomic_inc
(
&
kvm
->
mm
->
mm_count
);
atomic_inc
(
&
kvm
->
mm
->
mm_count
);
spin_lock_init
(
&
kvm
->
mmu_lock
);
spin_lock_init
(
&
kvm
->
mmu_lock
);
spin_lock_init
(
&
kvm
->
requests_lock
);
spin_lock_init
(
&
kvm
->
requests_lock
);
kvm_io_bus_init
(
&
kvm
->
pio_bus
);
kvm_eventfd_init
(
kvm
);
kvm_eventfd_init
(
kvm
);
mutex_init
(
&
kvm
->
lock
);
mutex_init
(
&
kvm
->
lock
);
mutex_init
(
&
kvm
->
irq_lock
);
mutex_init
(
&
kvm
->
irq_lock
);
kvm_io_bus_init
(
&
kvm
->
mmio_bus
);
init_rwsem
(
&
kvm
->
slots_lock
);
init_rwsem
(
&
kvm
->
slots_lock
);
atomic_set
(
&
kvm
->
users_count
,
1
);
atomic_set
(
&
kvm
->
users_count
,
1
);
spin_lock
(
&
kvm_lock
);
spin_lock
(
&
kvm_lock
);
...
@@ -435,6 +443,8 @@ static struct kvm *kvm_create_vm(void)
...
@@ -435,6 +443,8 @@ static struct kvm *kvm_create_vm(void)
out_err:
out_err:
hardware_disable_all
();
hardware_disable_all
();
out_err_nodisable:
out_err_nodisable:
for
(
i
=
0
;
i
<
KVM_NR_BUSES
;
i
++
)
kfree
(
kvm
->
buses
[
i
]);
kfree
(
kvm
->
memslots
);
kfree
(
kvm
->
memslots
);
kfree
(
kvm
);
kfree
(
kvm
);
return
ERR_PTR
(
r
);
return
ERR_PTR
(
r
);
...
@@ -480,6 +490,7 @@ void kvm_free_physmem(struct kvm *kvm)
...
@@ -480,6 +490,7 @@ void kvm_free_physmem(struct kvm *kvm)
static
void
kvm_destroy_vm
(
struct
kvm
*
kvm
)
static
void
kvm_destroy_vm
(
struct
kvm
*
kvm
)
{
{
int
i
;
struct
mm_struct
*
mm
=
kvm
->
mm
;
struct
mm_struct
*
mm
=
kvm
->
mm
;
kvm_arch_sync_events
(
kvm
);
kvm_arch_sync_events
(
kvm
);
...
@@ -487,8 +498,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
...
@@ -487,8 +498,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
list_del
(
&
kvm
->
vm_list
);
list_del
(
&
kvm
->
vm_list
);
spin_unlock
(
&
kvm_lock
);
spin_unlock
(
&
kvm_lock
);
kvm_free_irq_routing
(
kvm
);
kvm_free_irq_routing
(
kvm
);
kvm_io_bus_destroy
(
&
kvm
->
pio_bus
);
for
(
i
=
0
;
i
<
KVM_NR_BUSES
;
i
++
)
kvm_io_bus_destroy
(
&
kvm
->
mmio_bus
);
kvm_io_bus_destroy
(
kvm
->
buses
[
i
]
);
kvm_coalesced_mmio_free
(
kvm
);
kvm_coalesced_mmio_free
(
kvm
);
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
mmu_notifier_unregister
(
&
kvm
->
mmu_notifier
,
kvm
->
mm
);
mmu_notifier_unregister
(
&
kvm
->
mmu_notifier
,
kvm
->
mm
);
...
@@ -1949,12 +1960,7 @@ static struct notifier_block kvm_reboot_notifier = {
...
@@ -1949,12 +1960,7 @@ static struct notifier_block kvm_reboot_notifier = {
.
priority
=
0
,
.
priority
=
0
,
};
};
void
kvm_io_bus_init
(
struct
kvm_io_bus
*
bus
)
static
void
kvm_io_bus_destroy
(
struct
kvm_io_bus
*
bus
)
{
memset
(
bus
,
0
,
sizeof
(
*
bus
));
}
void
kvm_io_bus_destroy
(
struct
kvm_io_bus
*
bus
)
{
{
int
i
;
int
i
;
...
@@ -1963,13 +1969,15 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
...
@@ -1963,13 +1969,15 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
kvm_iodevice_destructor
(
pos
);
kvm_iodevice_destructor
(
pos
);
}
}
kfree
(
bus
);
}
}
/* kvm_io_bus_write - called under kvm->slots_lock */
/* kvm_io_bus_write - called under kvm->slots_lock */
int
kvm_io_bus_write
(
struct
kvm
_io_bus
*
bus
,
gpa_t
addr
,
int
kvm_io_bus_write
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
gpa_t
addr
,
int
len
,
const
void
*
val
)
int
len
,
const
void
*
val
)
{
{
int
i
;
int
i
;
struct
kvm_io_bus
*
bus
=
rcu_dereference
(
kvm
->
buses
[
bus_idx
]);
for
(
i
=
0
;
i
<
bus
->
dev_count
;
i
++
)
for
(
i
=
0
;
i
<
bus
->
dev_count
;
i
++
)
if
(
!
kvm_iodevice_write
(
bus
->
devs
[
i
],
addr
,
len
,
val
))
if
(
!
kvm_iodevice_write
(
bus
->
devs
[
i
],
addr
,
len
,
val
))
return
0
;
return
0
;
...
@@ -1977,59 +1985,71 @@ int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
...
@@ -1977,59 +1985,71 @@ int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
}
}
/* kvm_io_bus_read - called under kvm->slots_lock */
/* kvm_io_bus_read - called under kvm->slots_lock */
int
kvm_io_bus_read
(
struct
kvm_io_bus
*
bus
,
gpa_t
addr
,
int
len
,
void
*
val
)
int
kvm_io_bus_read
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
gpa_t
addr
,
int
len
,
void
*
val
)
{
{
int
i
;
int
i
;
struct
kvm_io_bus
*
bus
=
rcu_dereference
(
kvm
->
buses
[
bus_idx
]);
for
(
i
=
0
;
i
<
bus
->
dev_count
;
i
++
)
for
(
i
=
0
;
i
<
bus
->
dev_count
;
i
++
)
if
(
!
kvm_iodevice_read
(
bus
->
devs
[
i
],
addr
,
len
,
val
))
if
(
!
kvm_iodevice_read
(
bus
->
devs
[
i
],
addr
,
len
,
val
))
return
0
;
return
0
;
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
int
kvm_io_bus_register_dev
(
struct
kvm
*
kvm
,
struct
kvm_io_bus
*
bus
,
/* Caller must have write lock on slots_lock. */
struct
kvm_io_device
*
dev
)
int
kvm_io_bus_register_dev
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
struct
kvm_io_device
*
dev
)
{
{
int
ret
;
struct
kvm_io_bus
*
new_bus
,
*
bus
;
down_write
(
&
kvm
->
slots_lock
);
ret
=
__kvm_io_bus_register_dev
(
bus
,
dev
);
up_write
(
&
kvm
->
slots_lock
);
return
ret
;
bus
=
kvm
->
buses
[
bus_idx
];
}
/* An unlocked version. Caller must have write lock on slots_lock. */
int
__kvm_io_bus_register_dev
(
struct
kvm_io_bus
*
bus
,
struct
kvm_io_device
*
dev
)
{
if
(
bus
->
dev_count
>
NR_IOBUS_DEVS
-
1
)
if
(
bus
->
dev_count
>
NR_IOBUS_DEVS
-
1
)
return
-
ENOSPC
;
return
-
ENOSPC
;
bus
->
devs
[
bus
->
dev_count
++
]
=
dev
;
new_bus
=
kzalloc
(
sizeof
(
struct
kvm_io_bus
),
GFP_KERNEL
);
if
(
!
new_bus
)
return
-
ENOMEM
;
memcpy
(
new_bus
,
bus
,
sizeof
(
struct
kvm_io_bus
));
new_bus
->
devs
[
new_bus
->
dev_count
++
]
=
dev
;
rcu_assign_pointer
(
kvm
->
buses
[
bus_idx
],
new_bus
);
synchronize_srcu_expedited
(
&
kvm
->
srcu
);
kfree
(
bus
);
return
0
;
return
0
;
}
}
void
kvm_io_bus_unregister_dev
(
struct
kvm
*
kvm
,
/* Caller must have write lock on slots_lock. */
struct
kvm_io_bus
*
bus
,
int
kvm_io_bus_unregister_dev
(
struct
kvm
*
kvm
,
enum
kvm_bus
bus_idx
,
struct
kvm_io_device
*
dev
)
struct
kvm_io_device
*
dev
)
{
{
down_write
(
&
kvm
->
slots_lock
);
int
i
,
r
;
__kvm_io_bus_unregister_dev
(
bus
,
dev
);
struct
kvm_io_bus
*
new_bus
,
*
bus
;
up_write
(
&
kvm
->
slots_lock
);
}
/* An unlocked version. Caller must have write lock on slots_lock. */
new_bus
=
kzalloc
(
sizeof
(
struct
kvm_io_bus
),
GFP_KERNEL
);
void
__kvm_io_bus_unregister_dev
(
struct
kvm_io_bus
*
bus
,
if
(
!
new_bus
)
struct
kvm_io_device
*
dev
)
return
-
ENOMEM
;
{
int
i
;
for
(
i
=
0
;
i
<
bus
->
dev_count
;
i
++
)
bus
=
kvm
->
buses
[
bus_idx
];
if
(
bus
->
devs
[
i
]
==
dev
)
{
memcpy
(
new_bus
,
bus
,
sizeof
(
struct
kvm_io_bus
));
bus
->
devs
[
i
]
=
bus
->
devs
[
--
bus
->
dev_count
];
r
=
-
ENOENT
;
for
(
i
=
0
;
i
<
new_bus
->
dev_count
;
i
++
)
if
(
new_bus
->
devs
[
i
]
==
dev
)
{
r
=
0
;
new_bus
->
devs
[
i
]
=
new_bus
->
devs
[
--
new_bus
->
dev_count
];
break
;
break
;
}
}
if
(
r
)
{
kfree
(
new_bus
);
return
r
;
}
rcu_assign_pointer
(
kvm
->
buses
[
bus_idx
],
new_bus
);
synchronize_srcu_expedited
(
&
kvm
->
srcu
);
kfree
(
bus
);
return
r
;
}
}
static
struct
notifier_block
kvm_cpu_notifier
=
{
static
struct
notifier_block
kvm_cpu_notifier
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment