Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
5dbbda34
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5dbbda34
编写于
1月 20, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'mst/for_anthony' into staging
上级
d788b570
e10990c3
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
139 addition
and
29 deletion
+139
-29
docs/specs/acpi_pci_hotplug.txt
docs/specs/acpi_pci_hotplug.txt
+37
-0
hw/acpi_piix4.c
hw/acpi_piix4.c
+37
-0
hw/msi.c
hw/msi.c
+1
-4
hw/msix.c
hw/msix.c
+1
-4
hw/pci.c
hw/pci.c
+22
-5
hw/pci.h
hw/pci.h
+2
-0
hw/virtio-serial-bus.c
hw/virtio-serial-bus.c
+8
-2
migration.c
migration.c
+4
-0
savevm.c
savevm.c
+26
-14
sysemu.h
sysemu.h
+1
-0
未找到文件。
docs/specs/acpi_pci_hotplug.txt
0 → 100644
浏览文件 @
5dbbda34
QEMU<->ACPI BIOS PCI hotplug interface
--------------------------------------
QEMU supports PCI hotplug via ACPI, for PCI bus 0. This document
describes the interface between QEMU and the ACPI BIOS.
ACPI GPE block (IO ports 0xafe0-0xafe3, byte access):
-----------------------------------------
Generic ACPI GPE block. Bit 1 (GPE.1) used to notify PCI hotplug/eject
event to ACPI BIOS, via SCI interrupt.
PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access):
---------------------------------------------------------------
Slot injection notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of injection
events.
PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access):
-----------------------------------------------------
Slot removal notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of removal
events.
PCI device eject (IO port 0xae08-0xae0b, 4-byte access):
----------------------------------------
Used by ACPI BIOS _EJ0 method to request device removal. One bit per slot.
Reads return 0.
PCI removability status (IO port 0xae0c-0xae0f, 4-byte access):
-----------------------------------------------
Used by ACPI BIOS _RMV method to indicate removability status to OS. One
bit per slot.
hw/acpi_piix4.c
浏览文件 @
5dbbda34
...
...
@@ -37,6 +37,7 @@
#define GPE_BASE 0xafe0
#define PCI_BASE 0xae00
#define PCI_EJ_BASE 0xae08
#define PCI_RMV_BASE 0xae0c
#define PIIX4_PCI_HOTPLUG_STATUS 2
...
...
@@ -73,6 +74,7 @@ typedef struct PIIX4PMState {
/* for pci hotplug */
struct
gpe_regs
gpe
;
struct
pci_status
pci0_status
;
uint32_t
pci0_hotplug_enable
;
}
PIIX4PMState
;
static
void
piix4_acpi_system_hot_add_init
(
PCIBus
*
bus
,
PIIX4PMState
*
s
);
...
...
@@ -322,6 +324,25 @@ static const VMStateDescription vmstate_acpi = {
}
};
static
void
piix4_update_hotplug
(
PIIX4PMState
*
s
)
{
PCIDevice
*
dev
=
&
s
->
dev
;
BusState
*
bus
=
qdev_get_parent_bus
(
&
dev
->
qdev
);
DeviceState
*
qdev
,
*
next
;
s
->
pci0_hotplug_enable
=
~
0
;
QLIST_FOREACH_SAFE
(
qdev
,
&
bus
->
children
,
sibling
,
next
)
{
PCIDeviceInfo
*
info
=
container_of
(
qdev
->
info
,
PCIDeviceInfo
,
qdev
);
PCIDevice
*
pdev
=
DO_UPCAST
(
PCIDevice
,
qdev
,
qdev
);
int
slot
=
PCI_SLOT
(
pdev
->
devfn
);
if
(
info
->
no_hotplug
)
{
s
->
pci0_hotplug_enable
&=
~
(
1
<<
slot
);
}
}
}
static
void
piix4_reset
(
void
*
opaque
)
{
PIIX4PMState
*
s
=
opaque
;
...
...
@@ -336,6 +357,7 @@ static void piix4_reset(void *opaque)
/* Mark SMM as already inited (until KVM supports SMM). */
pci_conf
[
0x5B
]
=
0x02
;
}
piix4_update_hotplug
(
s
);
}
static
void
piix4_powerdown
(
void
*
opaque
,
int
irq
,
int
power_failing
)
...
...
@@ -576,6 +598,18 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
PIIX4_DPRINTF
(
"pciej write %x <== %d
\n
"
,
addr
,
val
);
}
static
uint32_t
pcirmv_read
(
void
*
opaque
,
uint32_t
addr
)
{
PIIX4PMState
*
s
=
opaque
;
return
s
->
pci0_hotplug_enable
;
}
static
void
pcirmv_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
{
return
;
}
static
int
piix4_device_hotplug
(
DeviceState
*
qdev
,
PCIDevice
*
dev
,
PCIHotplugState
state
);
...
...
@@ -592,6 +626,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
register_ioport_write
(
PCI_EJ_BASE
,
4
,
4
,
pciej_write
,
bus
);
register_ioport_read
(
PCI_EJ_BASE
,
4
,
4
,
pciej_read
,
bus
);
register_ioport_write
(
PCI_RMV_BASE
,
4
,
4
,
pcirmv_write
,
s
);
register_ioport_read
(
PCI_RMV_BASE
,
4
,
4
,
pcirmv_read
,
s
);
pci_bus_hotplug
(
bus
,
piix4_device_hotplug
,
&
s
->
dev
.
qdev
);
}
...
...
hw/msi.c
浏览文件 @
5dbbda34
...
...
@@ -255,7 +255,6 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
uint8_t
log_max_vecs
;
unsigned
int
vector
;
uint32_t
pending
;
int
i
;
if
(
!
ranges_overlap
(
addr
,
len
,
dev
->
msi_cap
,
msi_cap_sizeof
(
flags
)))
{
return
;
...
...
@@ -296,9 +295,7 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
* from using its INTx# pin (if implemented) to request
* service (MSI, MSI-X, and INTx# are mutually exclusive).
*/
for
(
i
=
0
;
i
<
PCI_NUM_PINS
;
++
i
)
{
qemu_set_irq
(
dev
->
irq
[
i
],
0
);
}
pci_device_deassert_intx
(
dev
);
/*
* nr_vectors might be set bigger than capable. So clamp it.
...
...
hw/msix.c
浏览文件 @
5dbbda34
...
...
@@ -159,7 +159,6 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
{
unsigned
enable_pos
=
dev
->
msix_cap
+
MSIX_CONTROL_OFFSET
;
int
vector
;
int
i
;
if
(
!
range_covers_byte
(
addr
,
len
,
enable_pos
))
{
return
;
...
...
@@ -169,9 +168,7 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
return
;
}
for
(
i
=
0
;
i
<
PCI_NUM_PINS
;
++
i
)
{
qemu_set_irq
(
dev
->
irq
[
i
],
0
);
}
pci_device_deassert_intx
(
dev
);
if
(
msix_function_masked
(
dev
))
{
return
;
...
...
hw/pci.c
浏览文件 @
5dbbda34
...
...
@@ -137,6 +137,14 @@ static void pci_update_irq_status(PCIDevice *dev)
}
}
void
pci_device_deassert_intx
(
PCIDevice
*
dev
)
{
int
i
;
for
(
i
=
0
;
i
<
PCI_NUM_PINS
;
++
i
)
{
qemu_set_irq
(
dev
->
irq
[
i
],
0
);
}
}
/*
* This function is called on #RST and FLR.
* FLR if PCI_EXP_DEVCTL_BCR_FLR is set
...
...
@@ -152,6 +160,7 @@ void pci_device_reset(PCIDevice *dev)
dev
->
irq_state
=
0
;
pci_update_irq_status
(
dev
);
pci_device_deassert_intx
(
dev
);
/* Clear all writeable bits */
pci_word_test_and_clear_mask
(
dev
->
config
+
PCI_COMMAND
,
pci_get_word
(
dev
->
wmask
+
PCI_COMMAND
)
|
...
...
@@ -2032,10 +2041,13 @@ static char *pcibus_get_dev_path(DeviceState *dev)
* domain:Bus:Slot.Func for systems without nested PCI bridges.
* Slot.Function list specifies the slot and function numbers for all
* devices on the path from root to the specific device. */
int
domain_len
=
strlen
(
"DDDD:00"
);
int
slot_len
=
strlen
(
":SS.F"
);
char
domain
[]
=
"DDDD:00"
;
char
slot
[]
=
":SS.F"
;
int
domain_len
=
sizeof
domain
-
1
/* For '\0' */
;
int
slot_len
=
sizeof
slot
-
1
/* For '\0' */
;
int
path_len
;
char
*
path
,
*
p
;
int
s
;
/* Calculate # of slots on path between device and root. */
;
slot_depth
=
0
;
...
...
@@ -2046,18 +2058,23 @@ static char *pcibus_get_dev_path(DeviceState *dev)
path_len
=
domain_len
+
slot_len
*
slot_depth
;
/* Allocate memory, fill in the terminating null byte. */
path
=
malloc
(
path_len
+
1
/* For '\0' */
);
path
=
qemu_
malloc
(
path_len
+
1
/* For '\0' */
);
path
[
path_len
]
=
'\0'
;
/* First field is the domain. */
snprintf
(
path
,
domain_len
,
"%04x:00"
,
pci_find_domain
(
d
->
bus
));
s
=
snprintf
(
domain
,
sizeof
domain
,
"%04x:00"
,
pci_find_domain
(
d
->
bus
));
assert
(
s
==
domain_len
);
memcpy
(
path
,
domain
,
domain_len
);
/* Fill in slot numbers. We walk up from device to root, so need to print
* them in the reverse order, last to first. */
p
=
path
+
path_len
;
for
(
t
=
d
;
t
;
t
=
t
->
bus
->
parent_dev
)
{
p
-=
slot_len
;
snprintf
(
p
,
slot_len
,
":%02x.%x"
,
PCI_SLOT
(
t
->
devfn
),
PCI_FUNC
(
d
->
devfn
));
s
=
snprintf
(
slot
,
sizeof
slot
,
":%02x.%x"
,
PCI_SLOT
(
t
->
devfn
),
PCI_FUNC
(
d
->
devfn
));
assert
(
s
==
slot_len
);
memcpy
(
p
,
slot
,
slot_len
);
}
return
path
;
...
...
hw/pci.h
浏览文件 @
5dbbda34
...
...
@@ -264,6 +264,8 @@ void do_pci_info_print(Monitor *mon, const QObject *data);
void
do_pci_info
(
Monitor
*
mon
,
QObject
**
ret_data
);
void
pci_bridge_update_mappings
(
PCIBus
*
b
);
void
pci_device_deassert_intx
(
PCIDevice
*
dev
);
static
inline
void
pci_set_byte
(
uint8_t
*
config
,
uint8_t
val
)
{
...
...
hw/virtio-serial-bus.c
浏览文件 @
5dbbda34
...
...
@@ -769,10 +769,16 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
/* Add a queue for guest to host transfers for port 0 (backward compat) */
vser
->
ovqs
[
0
]
=
virtio_add_queue
(
vdev
,
128
,
handle_output
);
/* TODO: host to guest notifications can get dropped
* if the queue fills up. Implement queueing in host,
* this might also make it possible to reduce the control
* queue size: as guest preposts buffers there,
* this will save 4Kbyte of guest memory per entry. */
/* control queue: host to guest */
vser
->
c_ivq
=
virtio_add_queue
(
vdev
,
16
,
control_in
);
vser
->
c_ivq
=
virtio_add_queue
(
vdev
,
32
,
control_in
);
/* control queue: guest to host */
vser
->
c_ovq
=
virtio_add_queue
(
vdev
,
16
,
control_out
);
vser
->
c_ovq
=
virtio_add_queue
(
vdev
,
32
,
control_out
);
for
(
i
=
1
;
i
<
vser
->
bus
->
max_nr_ports
;
i
++
)
{
/* Add a per-port queue for host to guest transfers */
...
...
migration.c
浏览文件 @
5dbbda34
...
...
@@ -88,6 +88,10 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
return
-
1
;
}
if
(
qemu_savevm_state_blocked
(
mon
))
{
return
-
1
;
}
if
(
strstart
(
uri
,
"tcp:"
,
&
p
))
{
s
=
tcp_start_outgoing_migration
(
mon
,
p
,
max_throttle
,
detach
,
blk
,
inc
);
...
...
savevm.c
浏览文件 @
5dbbda34
...
...
@@ -1401,19 +1401,13 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
return
vmstate_load_state
(
f
,
se
->
vmsd
,
se
->
opaque
,
version_id
);
}
static
int
vmstate_save
(
QEMUFile
*
f
,
SaveStateEntry
*
se
)
static
void
vmstate_save
(
QEMUFile
*
f
,
SaveStateEntry
*
se
)
{
if
(
se
->
no_migrate
)
{
return
-
1
;
}
if
(
!
se
->
vmsd
)
{
/* Old style */
se
->
save_state
(
f
,
se
->
opaque
);
return
0
;
return
;
}
vmstate_save_state
(
f
,
se
->
vmsd
,
se
->
opaque
);
return
0
;
}
#define QEMU_VM_FILE_MAGIC 0x5145564d
...
...
@@ -1427,6 +1421,20 @@ static int vmstate_save(QEMUFile *f, SaveStateEntry *se)
#define QEMU_VM_SECTION_FULL 0x04
#define QEMU_VM_SUBSECTION 0x05
bool
qemu_savevm_state_blocked
(
Monitor
*
mon
)
{
SaveStateEntry
*
se
;
QTAILQ_FOREACH
(
se
,
&
savevm_handlers
,
entry
)
{
if
(
se
->
no_migrate
)
{
monitor_printf
(
mon
,
"state blocked by non-migratable device '%s'
\n
"
,
se
->
idstr
);
return
true
;
}
}
return
false
;
}
int
qemu_savevm_state_begin
(
Monitor
*
mon
,
QEMUFile
*
f
,
int
blk_enable
,
int
shared
)
{
...
...
@@ -1508,7 +1516,6 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
int
qemu_savevm_state_complete
(
Monitor
*
mon
,
QEMUFile
*
f
)
{
SaveStateEntry
*
se
;
int
r
;
cpu_synchronize_all_states
();
...
...
@@ -1541,11 +1548,7 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
qemu_put_be32
(
f
,
se
->
instance_id
);
qemu_put_be32
(
f
,
se
->
version_id
);
r
=
vmstate_save
(
f
,
se
);
if
(
r
<
0
)
{
monitor_printf
(
mon
,
"cannot migrate with device '%s'
\n
"
,
se
->
idstr
);
return
r
;
}
vmstate_save
(
f
,
se
);
}
qemu_put_byte
(
f
,
QEMU_VM_EOF
);
...
...
@@ -1575,6 +1578,11 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
saved_vm_running
=
vm_running
;
vm_stop
(
0
);
if
(
qemu_savevm_state_blocked
(
mon
))
{
ret
=
-
EINVAL
;
goto
out
;
}
ret
=
qemu_savevm_state_begin
(
mon
,
f
,
0
,
0
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1692,6 +1700,10 @@ int qemu_loadvm_state(QEMUFile *f)
unsigned
int
v
;
int
ret
;
if
(
qemu_savevm_state_blocked
(
default_mon
))
{
return
-
EINVAL
;
}
v
=
qemu_get_be32
(
f
);
if
(
v
!=
QEMU_VM_FILE_MAGIC
)
return
-
EINVAL
;
...
...
sysemu.h
浏览文件 @
5dbbda34
...
...
@@ -75,6 +75,7 @@ void qemu_announce_self(void);
void
main_loop_wait
(
int
nonblocking
);
bool
qemu_savevm_state_blocked
(
Monitor
*
mon
);
int
qemu_savevm_state_begin
(
Monitor
*
mon
,
QEMUFile
*
f
,
int
blk_enable
,
int
shared
);
int
qemu_savevm_state_iterate
(
Monitor
*
mon
,
QEMUFile
*
f
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录