Compare commits
53 Commits
v9.0.0-rc1
...
v8.1.1
Author | SHA1 | Date | |
---|---|---|---|
|
6bb4a8a47a | ||
|
045fa84784 | ||
|
56270e5d3d | ||
|
60da8301fe | ||
|
8b479229ff | ||
|
d4919bbcc2 | ||
|
cae7dc1452 | ||
|
7385e00665 | ||
|
1d4fb5815c | ||
|
b822207513 | ||
|
2947da750e | ||
|
60a7f5c8fe | ||
|
566dac7127 | ||
|
8ae20123b6 | ||
|
6c24b6000b | ||
|
987e90cfd2 | ||
|
b9f83298b9 | ||
|
3d6251f416 | ||
|
9832a670b3 | ||
|
df33ce9b6d | ||
|
eeee989f72 | ||
|
93d4107937 | ||
|
6356785daa | ||
|
01bf87c8e3 | ||
|
25ec23ab3f | ||
|
9dc6f05cc8 | ||
|
d5361580ac | ||
|
e8f5ca57e4 | ||
|
4448c345bc | ||
|
4fbd5a5202 | ||
|
16cc9594d2 | ||
|
1efefd13ca | ||
|
c2e0495e3c | ||
|
f64f1f8704 | ||
|
9f54fef2c0 | ||
|
5358980d33 | ||
|
6864f05cb1 | ||
|
0175121c6c | ||
|
e975434d62 | ||
|
e5e77f256f | ||
|
645b87f650 | ||
|
86d7b08d71 | ||
|
5691fbf440 | ||
|
441106eebb | ||
|
63188a00bb | ||
|
7012e20b2d | ||
|
c8e381d672 | ||
|
34808d041c | ||
|
01f6417f15 | ||
|
14a8213b75 | ||
|
c12eddbd48 | ||
|
880e82ed78 | ||
|
5980189e96 |
@@ -2458,7 +2458,7 @@ static int kvm_init(MachineState *ms)
|
||||
KVMState *s;
|
||||
const KVMCapabilityInfo *missing_cap;
|
||||
int ret;
|
||||
int type = 0;
|
||||
int type;
|
||||
uint64_t dirty_log_manual_caps;
|
||||
|
||||
qemu_mutex_init(&kml_slots_lock);
|
||||
@@ -2523,6 +2523,8 @@ static int kvm_init(MachineState *ms)
|
||||
type = mc->kvm_type(ms, kvm_type);
|
||||
} else if (mc->kvm_type) {
|
||||
type = mc->kvm_type(ms, NULL);
|
||||
} else {
|
||||
type = kvm_arch_get_default_type(ms);
|
||||
}
|
||||
|
||||
do {
|
||||
|
@@ -112,12 +112,8 @@ static int tpm_util_request(int fd,
|
||||
void *response,
|
||||
size_t responselen)
|
||||
{
|
||||
fd_set readfds;
|
||||
GPollFD fds[1] = { {.fd = fd, .events = G_IO_IN } };
|
||||
int n;
|
||||
struct timeval tv = {
|
||||
.tv_sec = 1,
|
||||
.tv_usec = 0,
|
||||
};
|
||||
|
||||
n = write(fd, request, requestlen);
|
||||
if (n < 0) {
|
||||
@@ -127,11 +123,8 @@ static int tpm_util_request(int fd,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
|
||||
/* wait for a second */
|
||||
n = select(fd + 1, &readfds, NULL, NULL, &tv);
|
||||
n = RETRY_ON_EINTR(g_poll(fds, 1, 1000));
|
||||
if (n != 1) {
|
||||
return -errno;
|
||||
}
|
||||
|
@@ -8,4 +8,4 @@ QEMU is a trademark of Fabrice Bellard.
|
||||
QEMU is released under the `GNU General Public
|
||||
License <https://www.gnu.org/licenses/gpl-2.0.txt>`__, version 2. Parts
|
||||
of QEMU have specific licenses, see file
|
||||
`LICENSE <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=LICENSE>`__.
|
||||
`LICENSE <https://gitlab.com/qemu-project/qemu/-/raw/master/LICENSE>`__.
|
||||
|
@@ -117,13 +117,13 @@ to support the multiple thread compression migration:
|
||||
{qemu} migrate_set_capability compress on
|
||||
|
||||
3. Set the compression thread count on source:
|
||||
{qemu} migrate_set_parameter compress_threads 12
|
||||
{qemu} migrate_set_parameter compress-threads 12
|
||||
|
||||
4. Set the compression level on the source:
|
||||
{qemu} migrate_set_parameter compress_level 1
|
||||
{qemu} migrate_set_parameter compress-level 1
|
||||
|
||||
5. Set the decompression thread count on destination:
|
||||
{qemu} migrate_set_parameter decompress_threads 3
|
||||
{qemu} migrate_set_parameter decompress-threads 3
|
||||
|
||||
6. Start outgoing migration:
|
||||
{qemu} migrate -d tcp:destination.host:4444
|
||||
@@ -133,9 +133,9 @@ to support the multiple thread compression migration:
|
||||
|
||||
The following are the default settings:
|
||||
compress: off
|
||||
compress_threads: 8
|
||||
decompress_threads: 2
|
||||
compress_level: 1 (which means best speed)
|
||||
compress-threads: 8
|
||||
decompress-threads: 2
|
||||
compress-level: 1 (which means best speed)
|
||||
|
||||
So, only the first two steps are required to use the multiple
|
||||
thread compression in migration. You can do more if the default
|
||||
|
@@ -89,7 +89,7 @@ RUNNING:
|
||||
First, set the migration speed to match your hardware's capabilities:
|
||||
|
||||
QEMU Monitor Command:
|
||||
$ migrate_set_parameter max_bandwidth 40g # or whatever is the MAX of your RDMA device
|
||||
$ migrate_set_parameter max-bandwidth 40g # or whatever is the MAX of your RDMA device
|
||||
|
||||
Next, on the destination machine, add the following to the QEMU command line:
|
||||
|
||||
|
@@ -14,6 +14,7 @@ the following architecture extensions:
|
||||
- FEAT_BBM at level 2 (Translation table break-before-make levels)
|
||||
- FEAT_BF16 (AArch64 BFloat16 instructions)
|
||||
- FEAT_BTI (Branch Target Identification)
|
||||
- FEAT_CRC32 (CRC32 instructions)
|
||||
- FEAT_CSV2 (Cache speculation variant 2)
|
||||
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
|
||||
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "exec/tswap.h"
|
||||
#include "sysemu/dma.h"
|
||||
|
||||
#define RISCV_DEBUG_HTIF 0
|
||||
@@ -209,11 +210,11 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
|
||||
} else {
|
||||
uint64_t syscall[8];
|
||||
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
|
||||
if (syscall[0] == PK_SYS_WRITE &&
|
||||
syscall[1] == HTIF_DEV_CONSOLE &&
|
||||
syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
|
||||
if (tswap64(syscall[0]) == PK_SYS_WRITE &&
|
||||
tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
|
||||
tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
|
||||
uint8_t ch;
|
||||
cpu_physical_memory_read(syscall[2], &ch, 1);
|
||||
cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
|
||||
qemu_chr_fe_write(&s->chr, &ch, 1);
|
||||
resp = 0x100 | (uint8_t)payload;
|
||||
} else {
|
||||
@@ -232,7 +233,8 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
|
||||
s->tohost = 0; /* clear to indicate we read */
|
||||
return;
|
||||
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
|
||||
qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
|
||||
uint8_t ch = (uint8_t)payload;
|
||||
qemu_chr_fe_write(&s->chr, &ch, 1);
|
||||
resp = 0x100 | (uint8_t)payload;
|
||||
} else {
|
||||
qemu_log("HTIF device %d: unknown command\n", device);
|
||||
|
@@ -1591,7 +1591,10 @@ static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm)
|
||||
}
|
||||
|
||||
d->guest_slots[0].slot = slot;
|
||||
assert(qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0);
|
||||
if (qxl_add_memslot(d, 0, devmem, QXL_SYNC) != 0) {
|
||||
qxl_set_guest_bug(d, "device isn't initialized yet");
|
||||
return;
|
||||
}
|
||||
|
||||
d->guest_primary.surface = surface;
|
||||
qxl_create_guest_primary(d, 0, QXL_SYNC);
|
||||
|
@@ -1283,7 +1283,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle);
|
||||
#endif
|
||||
|
||||
res->addrs = g_new(uint64_t, res->iov_cnt);
|
||||
res->iov = g_new(struct iovec, res->iov_cnt);
|
||||
|
@@ -226,7 +226,7 @@ static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
|
||||
static int aspeed_i2c_bus_send(AspeedI2CBus *bus)
|
||||
{
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
|
||||
int ret = -1;
|
||||
@@ -236,10 +236,10 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
|
||||
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
int pool_tx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
|
||||
TX_COUNT);
|
||||
TX_COUNT) + 1;
|
||||
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
|
||||
for (i = pool_start; i < pool_tx_count; i++) {
|
||||
for (i = 0; i < pool_tx_count; i++) {
|
||||
uint8_t *pool_base = aic->bus_pool_base(bus);
|
||||
|
||||
trace_aspeed_i2c_bus_send("BUF", i + 1, pool_tx_count,
|
||||
@@ -273,7 +273,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
|
||||
}
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, TX_DMA_EN, 0);
|
||||
} else {
|
||||
trace_aspeed_i2c_bus_send("BYTE", pool_start, 1,
|
||||
trace_aspeed_i2c_bus_send("BYTE", 0, 1,
|
||||
bus->regs[reg_byte_buf]);
|
||||
ret = i2c_send(bus->bus, bus->regs[reg_byte_buf]);
|
||||
}
|
||||
@@ -293,7 +293,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
|
||||
int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
|
||||
RX_COUNT);
|
||||
RX_SIZE) + 1;
|
||||
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
|
||||
uint8_t *pool_base = aic->bus_pool_base(bus);
|
||||
@@ -418,7 +418,7 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
|
||||
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
|
||||
count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT);
|
||||
count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT) + 1;
|
||||
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_DMA_EN)) {
|
||||
count = bus->regs[reg_dma_len];
|
||||
} else { /* BYTE mode */
|
||||
@@ -446,10 +446,8 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
|
||||
*/
|
||||
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
|
||||
{
|
||||
uint8_t pool_start = 0;
|
||||
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
|
||||
uint32_t reg_cmd = aspeed_i2c_bus_cmd_offset(bus);
|
||||
uint32_t reg_pool_ctrl = aspeed_i2c_bus_pool_ctrl_offset(bus);
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
|
||||
if (!aspeed_i2c_check_sram(bus)) {
|
||||
@@ -483,27 +481,11 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
|
||||
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_START_CMD, 0);
|
||||
|
||||
/*
|
||||
* The START command is also a TX command, as the slave
|
||||
* address is sent on the bus. Drop the TX flag if nothing
|
||||
* else needs to be sent in this sequence.
|
||||
*/
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT)
|
||||
== 1) {
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
|
||||
} else {
|
||||
/*
|
||||
* Increase the start index in the TX pool buffer to
|
||||
* skip the address byte.
|
||||
*/
|
||||
pool_start++;
|
||||
}
|
||||
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
|
||||
if (bus->regs[reg_dma_len] == 0) {
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
|
||||
}
|
||||
} else {
|
||||
} else if (!SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
|
||||
}
|
||||
|
||||
@@ -520,7 +502,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
|
||||
|
||||
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, M_TX_CMD)) {
|
||||
aspeed_i2c_set_state(bus, I2CD_MTXD);
|
||||
if (aspeed_i2c_bus_send(bus, pool_start)) {
|
||||
if (aspeed_i2c_bus_send(bus)) {
|
||||
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, TX_NAK, 1);
|
||||
i2c_end_transfer(bus->bus);
|
||||
} else {
|
||||
|
110
hw/ide/ahci.c
110
hw/ide/ahci.c
@@ -41,9 +41,10 @@
|
||||
#include "trace.h"
|
||||
|
||||
static void check_cmd(AHCIState *s, int port);
|
||||
static int handle_cmd(AHCIState *s, int port, uint8_t slot);
|
||||
static void handle_cmd(AHCIState *s, int port, uint8_t slot);
|
||||
static void ahci_reset_port(AHCIState *s, int port);
|
||||
static bool ahci_write_fis_d2h(AHCIDevice *ad);
|
||||
static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i);
|
||||
static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot);
|
||||
static void ahci_init_d2h(AHCIDevice *ad);
|
||||
static int ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit);
|
||||
static bool ahci_map_clb_address(AHCIDevice *ad);
|
||||
@@ -328,6 +329,11 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
|
||||
ahci_check_irq(s);
|
||||
break;
|
||||
case AHCI_PORT_REG_CMD:
|
||||
if ((pr->cmd & PORT_CMD_START) && !(val & PORT_CMD_START)) {
|
||||
pr->scr_act = 0;
|
||||
pr->cmd_issue = 0;
|
||||
}
|
||||
|
||||
/* Block any Read-only fields from being set;
|
||||
* including LIST_ON and FIS_ON.
|
||||
* The spec requires to set ICC bits to zero after the ICC change
|
||||
@@ -591,9 +597,8 @@ static void check_cmd(AHCIState *s, int port)
|
||||
|
||||
if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
|
||||
for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
|
||||
if ((pr->cmd_issue & (1U << slot)) &&
|
||||
!handle_cmd(s, port, slot)) {
|
||||
pr->cmd_issue &= ~(1U << slot);
|
||||
if (pr->cmd_issue & (1U << slot)) {
|
||||
handle_cmd(s, port, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -618,7 +623,7 @@ static void ahci_init_d2h(AHCIDevice *ad)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ahci_write_fis_d2h(ad)) {
|
||||
if (ahci_write_fis_d2h(ad, true)) {
|
||||
ad->init_d2h_sent = true;
|
||||
/* We're emulating receiving the first Reg H2D Fis from the device;
|
||||
* Update the SIG register, but otherwise proceed as normal. */
|
||||
@@ -801,8 +806,14 @@ static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
|
||||
pr->scr_act &= ~ad->finished;
|
||||
ad->finished = 0;
|
||||
|
||||
/* Trigger IRQ if interrupt bit is set (which currently, it always is) */
|
||||
if (sdb_fis->flags & 0x40) {
|
||||
/*
|
||||
* TFES IRQ is always raised if ERR_STAT is set, regardless of I bit.
|
||||
* If ERR_STAT is not set, trigger SDBS IRQ if interrupt bit is set
|
||||
* (which currently, it always is).
|
||||
*/
|
||||
if (sdb_fis->status & ERR_STAT) {
|
||||
ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_TFES);
|
||||
} else if (sdb_fis->flags & 0x40) {
|
||||
ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
|
||||
}
|
||||
}
|
||||
@@ -850,7 +861,7 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len, bool pio_fis_i)
|
||||
}
|
||||
}
|
||||
|
||||
static bool ahci_write_fis_d2h(AHCIDevice *ad)
|
||||
static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i)
|
||||
{
|
||||
AHCIPortRegs *pr = &ad->port_regs;
|
||||
uint8_t *d2h_fis;
|
||||
@@ -864,7 +875,7 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
|
||||
d2h_fis = &ad->res_fis[RES_FIS_RFIS];
|
||||
|
||||
d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
|
||||
d2h_fis[1] = (1 << 6); /* interrupt bit */
|
||||
d2h_fis[1] = d2h_fis_i ? (1 << 6) : 0; /* interrupt bit */
|
||||
d2h_fis[2] = s->status;
|
||||
d2h_fis[3] = s->error;
|
||||
|
||||
@@ -890,7 +901,10 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
|
||||
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
|
||||
}
|
||||
|
||||
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
|
||||
if (d2h_fis_i) {
|
||||
ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -998,7 +1012,6 @@ static void ncq_err(NCQTransferState *ncq_tfs)
|
||||
|
||||
ide_state->error = ABRT_ERR;
|
||||
ide_state->status = READY_STAT | ERR_STAT;
|
||||
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
|
||||
qemu_sglist_destroy(&ncq_tfs->sglist);
|
||||
ncq_tfs->used = 0;
|
||||
}
|
||||
@@ -1008,7 +1021,7 @@ static void ncq_finish(NCQTransferState *ncq_tfs)
|
||||
/* If we didn't error out, set our finished bit. Errored commands
|
||||
* do not get a bit set for the SDB FIS ACT register, nor do they
|
||||
* clear the outstanding bit in scr_act (PxSACT). */
|
||||
if (!(ncq_tfs->drive->port_regs.scr_err & (1 << ncq_tfs->tag))) {
|
||||
if (ncq_tfs->used) {
|
||||
ncq_tfs->drive->finished |= (1 << ncq_tfs->tag);
|
||||
}
|
||||
|
||||
@@ -1120,6 +1133,24 @@ static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A NCQ command clears the bit in PxCI after the command has been QUEUED
|
||||
* successfully (ERROR not set, BUSY and DRQ cleared).
|
||||
*
|
||||
* For NCQ commands, PxCI will always be cleared here.
|
||||
*
|
||||
* (Once the NCQ command is COMPLETED, the device will send a SDB FIS with
|
||||
* the interrupt bit set, which will clear PxSACT and raise an interrupt.)
|
||||
*/
|
||||
ahci_clear_cmd_issue(ad, slot);
|
||||
|
||||
/*
|
||||
* In reality, for NCQ commands, PxCI is cleared after receiving a D2H FIS
|
||||
* without the interrupt bit set, but since ahci_write_fis_d2h() can raise
|
||||
* an IRQ on error, we need to call them in reverse order.
|
||||
*/
|
||||
ahci_write_fis_d2h(ad, false);
|
||||
|
||||
ncq_tfs->used = 1;
|
||||
ncq_tfs->drive = ad;
|
||||
ncq_tfs->slot = slot;
|
||||
@@ -1192,6 +1223,7 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
|
||||
{
|
||||
IDEState *ide_state = &s->dev[port].port.ifs[0];
|
||||
AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
|
||||
AHCIDevice *ad = &s->dev[port];
|
||||
uint16_t opts = le16_to_cpu(cmd->opts);
|
||||
|
||||
if (cmd_fis[1] & 0x0F) {
|
||||
@@ -1268,11 +1300,19 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
|
||||
/* Reset transferred byte counter */
|
||||
cmd->status = 0;
|
||||
|
||||
/*
|
||||
* A non-NCQ command clears the bit in PxCI after the command has COMPLETED
|
||||
* successfully (ERROR not set, BUSY and DRQ cleared).
|
||||
*
|
||||
* For non-NCQ commands, PxCI will always be cleared by ahci_cmd_done().
|
||||
*/
|
||||
ad->busy_slot = slot;
|
||||
|
||||
/* We're ready to process the command in FIS byte 2. */
|
||||
ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]);
|
||||
}
|
||||
|
||||
static int handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
static void handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
{
|
||||
IDEState *ide_state;
|
||||
uint64_t tbl_addr;
|
||||
@@ -1283,12 +1323,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
|
||||
/* Engine currently busy, try again later */
|
||||
trace_handle_cmd_busy(s, port);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s->dev[port].lst) {
|
||||
trace_handle_cmd_nolist(s, port);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
cmd = get_cmd_header(s, port, slot);
|
||||
/* remember current slot handle for later */
|
||||
@@ -1298,7 +1338,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
ide_state = &s->dev[port].port.ifs[0];
|
||||
if (!ide_state->blk) {
|
||||
trace_handle_cmd_badport(s, port);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
tbl_addr = le64_to_cpu(cmd->tbl_addr);
|
||||
@@ -1307,7 +1347,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
|
||||
if (!cmd_fis) {
|
||||
trace_handle_cmd_badfis(s, port);
|
||||
return -1;
|
||||
return;
|
||||
} else if (cmd_len != 0x80) {
|
||||
ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);
|
||||
trace_handle_cmd_badmap(s, port, cmd_len);
|
||||
@@ -1331,15 +1371,6 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
|
||||
out:
|
||||
dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
|
||||
cmd_len);
|
||||
|
||||
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
|
||||
/* async command, complete later */
|
||||
s->dev[port].busy_slot = slot;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* done handling the command */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Transfer PIO data between RAM and device */
|
||||
@@ -1493,22 +1524,39 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot)
|
||||
{
|
||||
IDEState *ide_state = &ad->port.ifs[0];
|
||||
|
||||
if (!(ide_state->status & ERR_STAT) &&
|
||||
!(ide_state->status & (BUSY_STAT | DRQ_STAT))) {
|
||||
ad->port_regs.cmd_issue &= ~(1 << slot);
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-NCQ command is done - This function is never called for NCQ commands. */
|
||||
static void ahci_cmd_done(const IDEDMA *dma)
|
||||
{
|
||||
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
|
||||
IDEState *ide_state = &ad->port.ifs[0];
|
||||
|
||||
trace_ahci_cmd_done(ad->hba, ad->port_no);
|
||||
|
||||
/* no longer busy */
|
||||
if (ad->busy_slot != -1) {
|
||||
ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
|
||||
ahci_clear_cmd_issue(ad, ad->busy_slot);
|
||||
ad->busy_slot = -1;
|
||||
}
|
||||
|
||||
/* update d2h status */
|
||||
ahci_write_fis_d2h(ad);
|
||||
/*
|
||||
* In reality, for non-NCQ commands, PxCI is cleared after receiving a D2H
|
||||
* FIS with the interrupt bit set, but since ahci_write_fis_d2h() will raise
|
||||
* an IRQ, we need to call them in reverse order.
|
||||
*/
|
||||
ahci_write_fis_d2h(ad, true);
|
||||
|
||||
if (ad->port_regs.cmd_issue && !ad->check_bh) {
|
||||
if (!(ide_state->status & ERR_STAT) &&
|
||||
ad->port_regs.cmd_issue && !ad->check_bh) {
|
||||
ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad,
|
||||
&ad->mem_reentrancy_guard);
|
||||
qemu_bh_schedule(ad->check_bh);
|
||||
|
@@ -533,9 +533,9 @@ BlockAIOCB *ide_issue_trim(
|
||||
|
||||
void ide_abort_command(IDEState *s)
|
||||
{
|
||||
ide_transfer_stop(s);
|
||||
s->status = READY_STAT | ERR_STAT;
|
||||
s->error = ABRT_ERR;
|
||||
ide_transfer_stop(s);
|
||||
}
|
||||
|
||||
static void ide_set_retry(IDEState *s)
|
||||
|
@@ -64,13 +64,13 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
|
||||
uint64_t next;
|
||||
uint64_t diff;
|
||||
|
||||
uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
|
||||
uint64_t rtc = cpu_riscv_read_rtc(mtimer);
|
||||
|
||||
/* Compute the relative hartid w.r.t the socket */
|
||||
hartid = hartid - mtimer->hartid_base;
|
||||
|
||||
mtimer->timecmp[hartid] = value;
|
||||
if (mtimer->timecmp[hartid] <= rtc_r) {
|
||||
if (mtimer->timecmp[hartid] <= rtc) {
|
||||
/*
|
||||
* If we're setting an MTIMECMP value in the "past",
|
||||
* immediately raise the timer interrupt
|
||||
@@ -81,7 +81,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
|
||||
|
||||
/* otherwise, set up the future timer interrupt */
|
||||
qemu_irq_lower(mtimer->timer_irqs[hartid]);
|
||||
diff = mtimer->timecmp[hartid] - rtc_r;
|
||||
diff = mtimer->timecmp[hartid] - rtc;
|
||||
/* back to ns (note args switched in muldiv64) */
|
||||
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
|
||||
|
||||
@@ -208,11 +208,12 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
|
||||
return;
|
||||
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
|
||||
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
|
||||
uint64_t rtc = cpu_riscv_read_rtc(mtimer);
|
||||
|
||||
if (addr == mtimer->time_base) {
|
||||
if (size == 4) {
|
||||
/* time_lo for RV32/RV64 */
|
||||
mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
|
||||
mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
|
||||
} else {
|
||||
/* time for RV64 */
|
||||
mtimer->time_delta = value - rtc_r;
|
||||
@@ -220,7 +221,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
|
||||
} else {
|
||||
if (size == 4) {
|
||||
/* time_hi for RV32/RV64 */
|
||||
mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
|
||||
mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"aclint-mtimer: invalid time_hi write: %08x",
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "qemu/datadir.h"
|
||||
#include "qapi/error.h"
|
||||
#include "elf.h"
|
||||
#include "kvm_mips.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/intc/loongson_liointc.h"
|
||||
#include "hw/mips/mips.h"
|
||||
@@ -612,7 +611,6 @@ static void loongson3v_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = LOONGSON_MAX_VCPUS;
|
||||
mc->default_ram_id = "loongson3.highram";
|
||||
mc->default_ram_size = 1600 * MiB;
|
||||
mc->kvm_type = mips_kvm_type;
|
||||
mc->minimum_page_bits = 14;
|
||||
mc->default_nic = "virtio-net-pci";
|
||||
}
|
||||
|
@@ -1439,7 +1439,10 @@ static void vmxnet3_activate_device(VMXNET3State *s)
|
||||
vmxnet3_setup_rx_filtering(s);
|
||||
/* Cache fields from shared memory */
|
||||
s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
|
||||
assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU);
|
||||
if (s->mtu < VMXNET3_MIN_MTU || s->mtu > VMXNET3_MAX_MTU) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "vmxnet3: Bad MTU size: %u\n", s->mtu);
|
||||
return;
|
||||
}
|
||||
VMW_CFPRN("MTU is %u", s->mtu);
|
||||
|
||||
s->max_rx_frags =
|
||||
|
@@ -712,7 +712,7 @@ static int ppce500_prep_device_tree(PPCE500MachineState *machine,
|
||||
p->kernel_base = kernel_base;
|
||||
p->kernel_size = kernel_size;
|
||||
|
||||
qemu_register_reset(ppce500_reset_device_tree, p);
|
||||
qemu_register_reset_nosnapshotload(ppce500_reset_device_tree, p);
|
||||
p->notifier.notify = ppce500_init_notify;
|
||||
qemu_add_machine_init_done_notifier(&p->notifier);
|
||||
|
||||
|
@@ -1024,6 +1024,8 @@ void vof_cleanup(Vof *vof)
|
||||
}
|
||||
vof->claimed = NULL;
|
||||
vof->of_instances = NULL;
|
||||
vof->of_instance_last = 0;
|
||||
vof->claimed_base = 0;
|
||||
}
|
||||
|
||||
void vof_build_dt(void *fdt, Vof *vof)
|
||||
|
@@ -732,7 +732,7 @@ static void create_fdt_pmu(RISCVVirtState *s)
|
||||
MachineState *ms = MACHINE(s);
|
||||
RISCVCPU hart = s->soc[0].harts[0];
|
||||
|
||||
pmu_name = g_strdup_printf("/soc/pmu");
|
||||
pmu_name = g_strdup_printf("/pmu");
|
||||
qemu_fdt_add_subnode(ms->fdt, pmu_name);
|
||||
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
|
||||
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
|
||||
|
@@ -109,6 +109,7 @@ static const char *const reset_dev_types[] = {
|
||||
"s390-flic",
|
||||
"diag288",
|
||||
TYPE_S390_PCI_HOST_BRIDGE,
|
||||
TYPE_AP_BRIDGE,
|
||||
};
|
||||
|
||||
static void subsystem_reset(void)
|
||||
|
@@ -2825,8 +2825,9 @@ static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
|
||||
}
|
||||
|
||||
/* A wrapper for use as a VMState .get function */
|
||||
static int virtio_device_get(QEMUFile *f, void *opaque, size_t size,
|
||||
const VMStateField *field)
|
||||
static int coroutine_mixed_fn
|
||||
virtio_device_get(QEMUFile *f, void *opaque, size_t size,
|
||||
const VMStateField *field)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
|
||||
DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev));
|
||||
@@ -2853,6 +2854,39 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val)
|
||||
return bad ? -1 : 0;
|
||||
}
|
||||
|
||||
typedef struct VirtioSetFeaturesNocheckData {
|
||||
Coroutine *co;
|
||||
VirtIODevice *vdev;
|
||||
uint64_t val;
|
||||
int ret;
|
||||
} VirtioSetFeaturesNocheckData;
|
||||
|
||||
static void virtio_set_features_nocheck_bh(void *opaque)
|
||||
{
|
||||
VirtioSetFeaturesNocheckData *data = opaque;
|
||||
|
||||
data->ret = virtio_set_features_nocheck(data->vdev, data->val);
|
||||
aio_co_wake(data->co);
|
||||
}
|
||||
|
||||
static int coroutine_mixed_fn
|
||||
virtio_set_features_nocheck_maybe_co(VirtIODevice *vdev, uint64_t val)
|
||||
{
|
||||
if (qemu_in_coroutine()) {
|
||||
VirtioSetFeaturesNocheckData data = {
|
||||
.co = qemu_coroutine_self(),
|
||||
.vdev = vdev,
|
||||
.val = val,
|
||||
};
|
||||
aio_bh_schedule_oneshot(qemu_get_current_aio_context(),
|
||||
virtio_set_features_nocheck_bh, &data);
|
||||
qemu_coroutine_yield();
|
||||
return data.ret;
|
||||
} else {
|
||||
return virtio_set_features_nocheck(vdev, val);
|
||||
}
|
||||
}
|
||||
|
||||
int virtio_set_features(VirtIODevice *vdev, uint64_t val)
|
||||
{
|
||||
int ret;
|
||||
@@ -2906,7 +2940,8 @@ size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
|
||||
return config_size;
|
||||
}
|
||||
|
||||
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
int coroutine_mixed_fn
|
||||
virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
{
|
||||
int i, ret;
|
||||
int32_t config_len;
|
||||
@@ -3023,14 +3058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
* host_features.
|
||||
*/
|
||||
uint64_t features64 = vdev->guest_features;
|
||||
if (virtio_set_features_nocheck(vdev, features64) < 0) {
|
||||
if (virtio_set_features_nocheck_maybe_co(vdev, features64) < 0) {
|
||||
error_report("Features 0x%" PRIx64 " unsupported. "
|
||||
"Allowed features: 0x%" PRIx64,
|
||||
features64, vdev->host_features);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (virtio_set_features_nocheck(vdev, features) < 0) {
|
||||
if (virtio_set_features_nocheck_maybe_co(vdev, features) < 0) {
|
||||
error_report("Features 0x%x unsupported. "
|
||||
"Allowed features: 0x%" PRIx64,
|
||||
features, vdev->host_features);
|
||||
|
@@ -139,9 +139,9 @@ REG32(I2CD_CMD, 0x14) /* I2CD Command/Status */
|
||||
REG32(I2CD_DEV_ADDR, 0x18) /* Slave Device Address */
|
||||
SHARED_FIELD(SLAVE_DEV_ADDR1, 0, 7)
|
||||
REG32(I2CD_POOL_CTRL, 0x1C) /* Pool Buffer Control */
|
||||
SHARED_FIELD(RX_COUNT, 24, 5)
|
||||
SHARED_FIELD(RX_COUNT, 24, 6)
|
||||
SHARED_FIELD(RX_SIZE, 16, 5)
|
||||
SHARED_FIELD(TX_COUNT, 9, 5)
|
||||
SHARED_FIELD(TX_COUNT, 8, 5)
|
||||
FIELD(I2CD_POOL_CTRL, OFFSET, 2, 6) /* AST2400 */
|
||||
REG32(I2CD_BYTE_BUF, 0x20) /* Transmit/Receive Byte Buffer */
|
||||
SHARED_FIELD(RX_BUF, 8, 8)
|
||||
|
@@ -63,7 +63,10 @@ virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
|
||||
{
|
||||
virtio_gpu_ctrl_hdr_bswap(&cblob->hdr);
|
||||
le32_to_cpus(&cblob->resource_id);
|
||||
le32_to_cpus(&cblob->blob_mem);
|
||||
le32_to_cpus(&cblob->blob_flags);
|
||||
le32_to_cpus(&cblob->nr_entries);
|
||||
le64_to_cpus(&cblob->blob_id);
|
||||
le64_to_cpus(&cblob->size);
|
||||
}
|
||||
|
||||
|
@@ -369,6 +369,8 @@ int kvm_arch_get_registers(CPUState *cpu);
|
||||
|
||||
int kvm_arch_put_registers(CPUState *cpu, int level);
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms);
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s);
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cpu);
|
||||
|
@@ -3204,7 +3204,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
||||
info->start_data = -1;
|
||||
info->end_data = 0;
|
||||
/* Usual start for brk is after all sections of the main executable. */
|
||||
info->brk = TARGET_PAGE_ALIGN(hiaddr);
|
||||
info->brk = TARGET_PAGE_ALIGN(hiaddr + load_bias);
|
||||
info->elf_flags = ehdr->e_flags;
|
||||
|
||||
prot_exec = PROT_EXEC;
|
||||
|
@@ -38,8 +38,8 @@ struct target_sigcontext {
|
||||
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
|
||||
|
||||
struct target_ucontext {
|
||||
unsigned long uc_flags;
|
||||
struct target_ucontext *uc_link;
|
||||
abi_ulong uc_flags;
|
||||
abi_ptr uc_link;
|
||||
target_stack_t uc_stack;
|
||||
target_sigset_t uc_sigmask;
|
||||
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
|
||||
|
@@ -225,7 +225,7 @@ if targetos == 'darwin'
|
||||
# Disable attempts to use ObjectiveC features in os/object.h since they
|
||||
# won't work when we're compiling with gcc as a C compiler.
|
||||
qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
|
||||
elif targetos == 'solaris'
|
||||
elif targetos == 'sunos'
|
||||
# needed for CMSG_ macros in sys/socket.h
|
||||
qemu_common_flags += '-D_XOPEN_SOURCE=600'
|
||||
# needed for TIOCWIN* defines in termios.h
|
||||
@@ -2056,7 +2056,7 @@ have_slirp_smbd = get_option('slirp_smbd') \
|
||||
if have_slirp_smbd
|
||||
smbd_path = get_option('smbd')
|
||||
if smbd_path == ''
|
||||
smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
|
||||
smbd_path = (targetos == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
|
||||
endif
|
||||
config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
|
||||
endif
|
||||
|
@@ -368,7 +368,9 @@ static void unset_dirty_tracking(void)
|
||||
BlkMigDevState *bmds;
|
||||
|
||||
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
|
||||
bdrv_release_dirty_bitmap(bmds->dirty_bitmap);
|
||||
if (bmds->dirty_bitmap) {
|
||||
bdrv_release_dirty_bitmap(bmds->dirty_bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -676,13 +678,18 @@ static int64_t get_remaining_dirty(void)
|
||||
static void block_migration_cleanup_bmds(void)
|
||||
{
|
||||
BlkMigDevState *bmds;
|
||||
BlockDriverState *bs;
|
||||
AioContext *ctx;
|
||||
|
||||
unset_dirty_tracking();
|
||||
|
||||
while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
|
||||
QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
|
||||
bdrv_op_unblock_all(blk_bs(bmds->blk), bmds->blocker);
|
||||
|
||||
bs = blk_bs(bmds->blk);
|
||||
if (bs) {
|
||||
bdrv_op_unblock_all(bs, bmds->blocker);
|
||||
}
|
||||
error_free(bmds->blocker);
|
||||
|
||||
/* Save ctx, because bmds->blk can disappear during blk_unref. */
|
||||
|
@@ -1209,10 +1209,10 @@ SRST
|
||||
ERST
|
||||
|
||||
DEF("hda", HAS_ARG, QEMU_OPTION_hda,
|
||||
"-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n", QEMU_ARCH_ALL)
|
||||
"-hda/-hdb file use 'file' as hard disk 0/1 image\n", QEMU_ARCH_ALL)
|
||||
DEF("hdb", HAS_ARG, QEMU_OPTION_hdb, "", QEMU_ARCH_ALL)
|
||||
DEF("hdc", HAS_ARG, QEMU_OPTION_hdc,
|
||||
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n", QEMU_ARCH_ALL)
|
||||
"-hdc/-hdd file use 'file' as hard disk 2/3 image\n", QEMU_ARCH_ALL)
|
||||
DEF("hdd", HAS_ARG, QEMU_OPTION_hdd, "", QEMU_ARCH_ALL)
|
||||
SRST
|
||||
``-hda file``
|
||||
@@ -1222,18 +1222,22 @@ SRST
|
||||
``-hdc file``
|
||||
\
|
||||
``-hdd file``
|
||||
Use file as hard disk 0, 1, 2 or 3 image (see the :ref:`disk images`
|
||||
chapter in the System Emulation Users Guide).
|
||||
Use file as hard disk 0, 1, 2 or 3 image on the default bus of the
|
||||
emulated machine (this is for example the IDE bus on most x86 machines,
|
||||
but it can also be SCSI, virtio or something else on other target
|
||||
architectures). See also the :ref:`disk images` chapter in the System
|
||||
Emulation Users Guide.
|
||||
ERST
|
||||
|
||||
DEF("cdrom", HAS_ARG, QEMU_OPTION_cdrom,
|
||||
"-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n",
|
||||
"-cdrom file use 'file' as CD-ROM image\n",
|
||||
QEMU_ARCH_ALL)
|
||||
SRST
|
||||
``-cdrom file``
|
||||
Use file as CD-ROM image (you cannot use ``-hdc`` and ``-cdrom`` at
|
||||
the same time). You can use the host CD-ROM by using ``/dev/cdrom``
|
||||
as filename.
|
||||
Use file as CD-ROM image on the default bus of the emulated machine
|
||||
(which is IDE1 master on x86, so you cannot use ``-hdc`` and ``-cdrom``
|
||||
at the same time there). On systems that support it, you can use the
|
||||
host CD-ROM by using ``/dev/cdrom`` as filename.
|
||||
ERST
|
||||
|
||||
DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
|
||||
|
@@ -2413,9 +2413,15 @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu,
|
||||
int asidx = cpu_asidx_from_attrs(cpu, attrs);
|
||||
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
|
||||
AddressSpaceDispatch *d = qatomic_rcu_read(&cpuas->memory_dispatch);
|
||||
MemoryRegionSection *sections = d->map.sections;
|
||||
int section_index = index & ~TARGET_PAGE_MASK;
|
||||
MemoryRegionSection *ret;
|
||||
|
||||
return §ions[index & ~TARGET_PAGE_MASK];
|
||||
assert(section_index < d->map.sections_nb);
|
||||
ret = d->map.sections + section_index;
|
||||
assert(ret->mr);
|
||||
assert(ret->mr->ops);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void io_mem_init(void)
|
||||
|
@@ -247,6 +247,13 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
|
||||
return ret > 0 ? ret : 40;
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
bool fixed_ipa;
|
||||
int size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
|
||||
return fixed_ipa ? 0 : size;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@@ -674,6 +674,7 @@ typedef struct CPRegStateLevel {
|
||||
*/
|
||||
static const CPRegStateLevel non_runtime_cpregs[] = {
|
||||
{ KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
|
||||
{ KVM_REG_ARM_PTIMER_CNT, KVM_PUT_FULL_STATE },
|
||||
};
|
||||
|
||||
int kvm_arm_cpreg_level(uint64_t regidx)
|
||||
|
@@ -743,7 +743,7 @@ void aarch64_max_tcg_initfn(Object *obj)
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1); /* FEAT_CRC32 */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
|
||||
|
@@ -379,7 +379,7 @@ static inline void HNAME##_host(void *za, intptr_t off, void *host) \
|
||||
{ \
|
||||
uint64_t *ptr = za + off; \
|
||||
HOST(host, ptr[BE]); \
|
||||
HOST(host + 1, ptr[!BE]); \
|
||||
HOST(host + 8, ptr[!BE]); \
|
||||
} \
|
||||
static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
|
||||
{ \
|
||||
|
@@ -3053,7 +3053,7 @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_ssra64_i64,
|
||||
.fniv = gen_ssra_vec,
|
||||
.fno = gen_helper_gvec_ssra_b,
|
||||
.fno = gen_helper_gvec_ssra_d,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.opt_opc = vecop_list,
|
||||
.load_dest = true,
|
||||
|
@@ -2556,6 +2556,11 @@ static void register_smram_listener(Notifier *n, void *unused)
|
||||
&smram_address_space, 1, "kvm-smram");
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
uint64_t identity_base = 0xfffbc000;
|
||||
|
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "cpu.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
@@ -31,7 +32,9 @@ void x86_register_ferr_irq(qemu_irq irq)
|
||||
void fpu_check_raise_ferr_irq(CPUX86State *env)
|
||||
{
|
||||
if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) {
|
||||
qemu_mutex_lock_iothread();
|
||||
qemu_irq_raise(ferr_irq);
|
||||
qemu_mutex_unlock_iothread();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -45,6 +48,9 @@ void cpu_clear_ignne(void)
|
||||
void cpu_set_ignne(void)
|
||||
{
|
||||
CPUX86State *env = &X86_CPU(first_cpu)->env;
|
||||
|
||||
assert(qemu_mutex_iothread_locked());
|
||||
|
||||
env->hflags2 |= HF2_IGNNE_MASK;
|
||||
/*
|
||||
* We get here in response to a write to port F0h. The chipset should
|
||||
|
@@ -4619,7 +4619,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x0a: /* grp d9/2 */
|
||||
switch (rm) {
|
||||
case 0: /* fnop */
|
||||
/* check exceptions (FreeBSD FPU probe) */
|
||||
/*
|
||||
* check exceptions (FreeBSD FPU probe)
|
||||
* needs to be treated as I/O because of ferr_irq
|
||||
*/
|
||||
translator_io_start(&s->base);
|
||||
gen_helper_fwait(cpu_env);
|
||||
update_fip = false;
|
||||
break;
|
||||
@@ -5548,6 +5552,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
||||
(HF_MP_MASK | HF_TS_MASK)) {
|
||||
gen_exception(s, EXCP07_PREX);
|
||||
} else {
|
||||
/* needs to be treated as I/O because of ferr_irq */
|
||||
translator_io_start(&s->base);
|
||||
gen_helper_fwait(cpu_env);
|
||||
}
|
||||
break;
|
||||
|
@@ -1266,7 +1266,7 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
|
||||
abort();
|
||||
}
|
||||
|
||||
int mips_kvm_type(MachineState *machine, const char *vm_type)
|
||||
int kvm_arch_get_default_type(MachineState *machine)
|
||||
{
|
||||
#if defined(KVM_CAP_MIPS_VZ)
|
||||
int r;
|
||||
|
@@ -25,13 +25,4 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
|
||||
int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
|
||||
int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
int mips_kvm_type(MachineState *machine, const char *vm_type);
|
||||
#else
|
||||
static inline int mips_kvm_type(MachineState *machine, const char *vm_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KVM_MIPS_H */
|
||||
|
@@ -59,6 +59,7 @@ void ppc_store_vscr(CPUPPCState *env, uint32_t vscr)
|
||||
env->vscr_sat.u64[0] = vscr & (1u << VSCR_SAT);
|
||||
env->vscr_sat.u64[1] = 0;
|
||||
set_flush_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status);
|
||||
set_flush_inputs_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status);
|
||||
}
|
||||
|
||||
uint32_t ppc_get_vscr(CPUPPCState *env)
|
||||
|
@@ -108,6 +108,11 @@ static int kvm_ppc_register_host_cpu_type(void);
|
||||
static void kvmppc_get_cpu_characteristics(KVMState *s);
|
||||
static int kvmppc_get_dec_bits(void);
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
|
||||
|
@@ -71,7 +71,7 @@ static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed)
|
||||
{
|
||||
#if defined(TARGET_PPC64)
|
||||
TCGv ea;
|
||||
TCGv_i64 low_addr_gpr, high_addr_gpr;
|
||||
TCGv_i64 lo, hi;
|
||||
TCGv_i128 t16;
|
||||
|
||||
REQUIRE_INSNS_FLAGS(ctx, 64BX);
|
||||
@@ -94,21 +94,21 @@ static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed)
|
||||
gen_set_access_type(ctx, ACCESS_INT);
|
||||
ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->si));
|
||||
|
||||
if (prefixed || !ctx->le_mode) {
|
||||
low_addr_gpr = cpu_gpr[a->rt];
|
||||
high_addr_gpr = cpu_gpr[a->rt + 1];
|
||||
if (ctx->le_mode && prefixed) {
|
||||
lo = cpu_gpr[a->rt];
|
||||
hi = cpu_gpr[a->rt + 1];
|
||||
} else {
|
||||
low_addr_gpr = cpu_gpr[a->rt + 1];
|
||||
high_addr_gpr = cpu_gpr[a->rt];
|
||||
lo = cpu_gpr[a->rt + 1];
|
||||
hi = cpu_gpr[a->rt];
|
||||
}
|
||||
t16 = tcg_temp_new_i128();
|
||||
|
||||
if (store) {
|
||||
tcg_gen_concat_i64_i128(t16, low_addr_gpr, high_addr_gpr);
|
||||
tcg_gen_concat_i64_i128(t16, lo, hi);
|
||||
tcg_gen_qemu_st_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128));
|
||||
} else {
|
||||
tcg_gen_qemu_ld_i128(t16, ea, ctx->mem_idx, DEF_MEMOP(MO_128));
|
||||
tcg_gen_extr_i128_i64(low_addr_gpr, high_addr_gpr, t16);
|
||||
tcg_gen_extr_i128_i64(lo, hi, t16);
|
||||
}
|
||||
#else
|
||||
qemu_build_not_reached();
|
||||
|
@@ -88,6 +88,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
|
||||
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
|
||||
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
|
||||
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
|
||||
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
|
||||
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
|
||||
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
|
||||
@@ -298,6 +299,17 @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
|
||||
|
||||
uint8_t satp_mode_max_from_map(uint32_t map)
|
||||
{
|
||||
/*
|
||||
* 'map = 0' will make us return (31 - 32), which C will
|
||||
* happily overflow to UINT_MAX. There's no good result to
|
||||
* return if 'map = 0' (e.g. returning 0 will be ambiguous
|
||||
* with the result for 'map = 1').
|
||||
*
|
||||
* Assert out if map = 0. Callers will have to deal with
|
||||
* it outside of this function.
|
||||
*/
|
||||
g_assert(map > 0);
|
||||
|
||||
/* map here has at least one bit set, so no problem with clz */
|
||||
return 31 - __builtin_clz(map);
|
||||
}
|
||||
@@ -904,7 +916,7 @@ static void riscv_cpu_reset_hold(Object *obj)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (cpu->cfg.debug) {
|
||||
riscv_trigger_init(env);
|
||||
riscv_trigger_reset_hold(env);
|
||||
}
|
||||
|
||||
if (kvm_enabled()) {
|
||||
@@ -1303,9 +1315,15 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
|
||||
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
|
||||
{
|
||||
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
|
||||
uint8_t satp_mode_map_max;
|
||||
uint8_t satp_mode_supported_max =
|
||||
satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
|
||||
uint8_t satp_mode_map_max, satp_mode_supported_max;
|
||||
|
||||
/* The CPU wants the OS to decide which satp mode to use */
|
||||
if (cpu->cfg.satp_mode.supported == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
satp_mode_supported_max =
|
||||
satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
|
||||
|
||||
if (cpu->cfg.satp_mode.map == 0) {
|
||||
if (cpu->cfg.satp_mode.init == 0) {
|
||||
@@ -1473,6 +1491,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
riscv_cpu_register_gdb_regs_for_features(cs);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (cpu->cfg.debug) {
|
||||
riscv_trigger_realize(&cpu->env);
|
||||
}
|
||||
#endif
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
cpu_reset(cs);
|
||||
|
||||
|
@@ -903,7 +903,17 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
|
||||
return false;
|
||||
}
|
||||
|
||||
void riscv_trigger_init(CPURISCVState *env)
|
||||
void riscv_trigger_realize(CPURISCVState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RV_MAX_TRIGGERS; i++) {
|
||||
env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
riscv_itrigger_timer_cb, env);
|
||||
}
|
||||
}
|
||||
|
||||
void riscv_trigger_reset_hold(CPURISCVState *env)
|
||||
{
|
||||
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
|
||||
int i;
|
||||
@@ -928,7 +938,6 @@ void riscv_trigger_init(CPURISCVState *env)
|
||||
env->tdata3[i] = 0;
|
||||
env->cpu_breakpoint[i] = NULL;
|
||||
env->cpu_watchpoint[i] = NULL;
|
||||
env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
riscv_itrigger_timer_cb, env);
|
||||
timer_del(env->itrigger_timer[i]);
|
||||
}
|
||||
}
|
||||
|
@@ -143,7 +143,8 @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
|
||||
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
|
||||
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
|
||||
|
||||
void riscv_trigger_init(CPURISCVState *env);
|
||||
void riscv_trigger_realize(CPURISCVState *env);
|
||||
void riscv_trigger_reset_hold(CPURISCVState *env);
|
||||
|
||||
bool riscv_itrigger_enabled(CPURISCVState *env);
|
||||
void riscv_itrigger_update_priv(CPURISCVState *env);
|
||||
|
@@ -470,7 +470,7 @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
|
||||
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
|
||||
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
|
||||
|
||||
gen_helper_fltq_s(dest, cpu_env, src1, src2);
|
||||
gen_helper_fleq_d(dest, cpu_env, src1, src2);
|
||||
gen_set_gpr(ctx, a->rd, dest);
|
||||
return true;
|
||||
}
|
||||
@@ -485,7 +485,7 @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
|
||||
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
|
||||
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
|
||||
|
||||
gen_helper_fltq_s(dest, cpu_env, src1, src2);
|
||||
gen_helper_fltq_d(dest, cpu_env, src1, src2);
|
||||
gen_set_gpr(ctx, a->rd, dest);
|
||||
return true;
|
||||
}
|
||||
|
@@ -914,6 +914,11 @@ int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
return 0;
|
||||
|
@@ -44,6 +44,10 @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
|
||||
*/
|
||||
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
|
||||
{
|
||||
/* mseccfg.RLB is set */
|
||||
if (MSECCFG_RLB_ISSET(env)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
|
||||
return 1;
|
||||
|
@@ -583,7 +583,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
|
||||
cpu_mmu_index(env, false));
|
||||
if (host) {
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
if (page_check_range(addr, offset, PAGE_READ)) {
|
||||
if (!page_check_range(addr, offset, PAGE_READ)) {
|
||||
vl = i;
|
||||
goto ProbeSuccess;
|
||||
}
|
||||
|
@@ -340,6 +340,11 @@ static void ccw_machine_class_foreach(ObjectClass *oc, void *opaque)
|
||||
mc->default_cpu_type = S390_CPU_TYPE_NAME("host");
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
object_class_foreach(ccw_machine_class_foreach, TYPE_S390_CCW_MACHINE,
|
||||
|
@@ -57,7 +57,7 @@
|
||||
#define FPF_LONG 3
|
||||
#define FPF_EXT 4
|
||||
|
||||
static inline bool valid_vec_element(uint8_t enr, MemOp es)
|
||||
static inline bool valid_vec_element(uint16_t enr, MemOp es)
|
||||
{
|
||||
return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
|
||||
}
|
||||
@@ -964,7 +964,7 @@ static DisasJumpType op_vpdi(DisasContext *s, DisasOps *o)
|
||||
|
||||
static DisasJumpType op_vrep(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
const uint8_t enr = get_field(s, i2);
|
||||
const uint16_t enr = get_field(s, i2);
|
||||
const uint8_t es = get_field(s, m4);
|
||||
|
||||
if (es > ES_64 || !valid_vec_element(enr, es)) {
|
||||
@@ -3047,7 +3047,7 @@ static DisasJumpType op_vfmax(DisasContext *s, DisasOps *o)
|
||||
const uint8_t m5 = get_field(s, m5);
|
||||
gen_helper_gvec_3_ptr *fn;
|
||||
|
||||
if (m6 == 5 || m6 == 6 || m6 == 7 || m6 >= 13) {
|
||||
if (m6 == 5 || m6 == 6 || m6 == 7 || m6 >= 13 || (m5 & 7)) {
|
||||
gen_program_exception(s, PGM_SPECIFICATION);
|
||||
return DISAS_NORETURN;
|
||||
}
|
||||
|
@@ -193,7 +193,7 @@ void HELPER(vstl)(CPUS390XState *env, const void *v1, uint64_t addr,
|
||||
uint64_t bytes)
|
||||
{
|
||||
/* Probe write access before actually modifying memory */
|
||||
probe_write_access(env, addr, bytes, GETPC());
|
||||
probe_write_access(env, addr, MIN(bytes, 16), GETPC());
|
||||
|
||||
if (likely(bytes >= 16)) {
|
||||
cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 0), GETPC());
|
||||
|
@@ -474,9 +474,9 @@ DEF_VSTRC_CC_RT_HELPER(32)
|
||||
static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
|
||||
const S390Vector *v4, uint8_t es, bool zs)
|
||||
{
|
||||
int substr_elen, substr_0, str_elen, i, j, k, cc;
|
||||
int substr_elen, i, j, k, cc;
|
||||
int nelem = 16 >> es;
|
||||
bool eos = false;
|
||||
int str_leftmost_0;
|
||||
|
||||
substr_elen = s390_vec_read_element8(v4, 7) >> es;
|
||||
|
||||
@@ -498,47 +498,20 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
|
||||
}
|
||||
|
||||
/* If ZS, look for eos in the searched string. */
|
||||
str_leftmost_0 = nelem;
|
||||
if (zs) {
|
||||
for (k = 0; k < nelem; k++) {
|
||||
if (s390_vec_read_element(v2, k, es) == 0) {
|
||||
eos = true;
|
||||
str_leftmost_0 = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str_elen = k;
|
||||
} else {
|
||||
str_elen = nelem;
|
||||
}
|
||||
|
||||
substr_0 = s390_vec_read_element(v3, 0, es);
|
||||
|
||||
for (k = 0; ; k++) {
|
||||
for (; k < str_elen; k++) {
|
||||
if (s390_vec_read_element(v2, k, es) == substr_0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we reached the end of the string, no match. */
|
||||
if (k == str_elen) {
|
||||
cc = eos; /* no match (with or without zero char) */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the substring is only one char, match. */
|
||||
if (substr_elen == 1) {
|
||||
cc = 2; /* full match */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the match begins at the last char, we have a partial match. */
|
||||
if (k == str_elen - 1) {
|
||||
cc = 3; /* partial match */
|
||||
goto done;
|
||||
}
|
||||
|
||||
cc = str_leftmost_0 == nelem ? 0 : 1; /* No match. */
|
||||
for (k = 0; k < nelem; k++) {
|
||||
i = MIN(nelem, k + substr_elen);
|
||||
for (j = k + 1; j < i; j++) {
|
||||
for (j = k; j < i; j++) {
|
||||
uint32_t e2 = s390_vec_read_element(v2, j, es);
|
||||
uint32_t e3 = s390_vec_read_element(v3, j - k, es);
|
||||
if (e2 != e3) {
|
||||
@@ -546,9 +519,16 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
|
||||
}
|
||||
}
|
||||
if (j == i) {
|
||||
/* Matched up until "end". */
|
||||
cc = i - k == substr_elen ? 2 : 3; /* full or partial match */
|
||||
goto done;
|
||||
/* All elements matched. */
|
||||
if (k > str_leftmost_0) {
|
||||
cc = 1; /* Ignored match. */
|
||||
k = nelem;
|
||||
} else if (i - k == substr_elen) {
|
||||
cc = 2; /* Full match. */
|
||||
} else {
|
||||
cc = 3; /* Partial match. */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -109,7 +109,7 @@ if [ ${QEMU_STATUS[$dest]} -lt 0 ]; then
|
||||
_notrun 'Postcopy is not supported'
|
||||
fi
|
||||
|
||||
_send_qemu_cmd $src 'migrate_set_parameter max_bandwidth 4k' "(qemu)"
|
||||
_send_qemu_cmd $src 'migrate_set_parameter max-bandwidth 4k' "(qemu)"
|
||||
_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)"
|
||||
_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)"
|
||||
_send_qemu_cmd $src 'migrate_start_postcopy' "(qemu)"
|
||||
|
@@ -404,57 +404,110 @@ void ahci_port_clear(AHCIQState *ahci, uint8_t port)
|
||||
/**
|
||||
* Check a port for errors.
|
||||
*/
|
||||
void ahci_port_check_error(AHCIQState *ahci, uint8_t port,
|
||||
uint32_t imask, uint8_t emask)
|
||||
void ahci_port_check_error(AHCIQState *ahci, AHCICommand *cmd)
|
||||
{
|
||||
uint8_t port = cmd->port;
|
||||
uint32_t reg;
|
||||
|
||||
/* The upper 9 bits of the IS register all indicate errors. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
|
||||
reg &= ~imask;
|
||||
reg >>= 23;
|
||||
g_assert_cmphex(reg, ==, 0);
|
||||
/* If expecting TF error, ensure that TFES is set. */
|
||||
if (cmd->errors) {
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
|
||||
ASSERT_BIT_SET(reg, AHCI_PX_IS_TFES);
|
||||
} else {
|
||||
/* The upper 9 bits of the IS register all indicate errors. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
|
||||
reg &= ~cmd->interrupts;
|
||||
reg >>= 23;
|
||||
g_assert_cmphex(reg, ==, 0);
|
||||
}
|
||||
|
||||
/* The Sata Error Register should be empty. */
|
||||
/* The Sata Error Register should be empty, even when expecting TF error. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_SERR);
|
||||
g_assert_cmphex(reg, ==, 0);
|
||||
|
||||
/* If expecting TF error, and TFES was set, perform error recovery
|
||||
* (see AHCI 1.3 section 6.2.2.1) such that we can send new commands. */
|
||||
if (cmd->errors) {
|
||||
/* This will clear PxCI. */
|
||||
ahci_px_clr(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
|
||||
|
||||
/* The port has 500ms to disengage. */
|
||||
usleep(500000);
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_CMD);
|
||||
ASSERT_BIT_CLEAR(reg, AHCI_PX_CMD_CR);
|
||||
|
||||
/* Clear PxIS. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
|
||||
ahci_px_wreg(ahci, port, AHCI_PX_IS, reg);
|
||||
|
||||
/* Check if we need to perform a COMRESET.
|
||||
* Not implemented right now, as there is no reason why our QEMU model
|
||||
* should need a COMRESET when expecting TF error. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD);
|
||||
ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_BSY | AHCI_PX_TFD_STS_DRQ);
|
||||
|
||||
/* Enable issuing new commands. */
|
||||
ahci_px_set(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
|
||||
}
|
||||
|
||||
/* The TFD also has two error sections. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD);
|
||||
if (!emask) {
|
||||
if (!cmd->errors) {
|
||||
ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_ERR);
|
||||
} else {
|
||||
ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_ERR);
|
||||
}
|
||||
ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR & (~emask << 8));
|
||||
ASSERT_BIT_SET(reg, AHCI_PX_TFD_ERR & (emask << 8));
|
||||
ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR & (~cmd->errors << 8));
|
||||
ASSERT_BIT_SET(reg, AHCI_PX_TFD_ERR & (cmd->errors << 8));
|
||||
}
|
||||
|
||||
void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
|
||||
uint32_t intr_mask)
|
||||
void ahci_port_check_interrupts(AHCIQState *ahci, AHCICommand *cmd)
|
||||
{
|
||||
uint8_t port = cmd->port;
|
||||
uint32_t reg;
|
||||
|
||||
/* If we expect errors, error handling in ahci_port_check_error() will
|
||||
* already have cleared PxIS, so in that case this function cannot verify
|
||||
* and clear expected interrupts. */
|
||||
if (cmd->errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for expected interrupts */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
|
||||
ASSERT_BIT_SET(reg, intr_mask);
|
||||
ASSERT_BIT_SET(reg, cmd->interrupts);
|
||||
|
||||
/* Clear expected interrupts and assert all interrupts now cleared. */
|
||||
ahci_px_wreg(ahci, port, AHCI_PX_IS, intr_mask);
|
||||
ahci_px_wreg(ahci, port, AHCI_PX_IS, cmd->interrupts);
|
||||
g_assert_cmphex(ahci_px_rreg(ahci, port, AHCI_PX_IS), ==, 0);
|
||||
}
|
||||
|
||||
void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot)
|
||||
void ahci_port_check_nonbusy(AHCIQState *ahci, AHCICommand *cmd)
|
||||
{
|
||||
uint8_t slot = cmd->slot;
|
||||
uint8_t port = cmd->port;
|
||||
uint32_t reg;
|
||||
|
||||
/* Assert that the command slot is no longer busy (NCQ) */
|
||||
/* For NCQ command with error PxSACT bit should still be set.
|
||||
* For NCQ command without error, PxSACT bit should be cleared.
|
||||
* For non-NCQ command, PxSACT bit should always be cleared. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_SACT);
|
||||
ASSERT_BIT_CLEAR(reg, (1 << slot));
|
||||
if (cmd->props->ncq && cmd->errors) {
|
||||
ASSERT_BIT_SET(reg, (1 << slot));
|
||||
} else {
|
||||
ASSERT_BIT_CLEAR(reg, (1 << slot));
|
||||
}
|
||||
|
||||
/* Non-NCQ */
|
||||
/* For non-NCQ command with error, PxCI bit should still be set.
|
||||
* For non-NCQ command without error, PxCI bit should be cleared.
|
||||
* For NCQ command without error, PxCI bit should be cleared.
|
||||
* For NCQ command with error, PxCI bit may or may not be cleared. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_CI);
|
||||
ASSERT_BIT_CLEAR(reg, (1 << slot));
|
||||
if (!cmd->props->ncq && cmd->errors) {
|
||||
ASSERT_BIT_SET(reg, (1 << slot));
|
||||
} else if (!cmd->errors) {
|
||||
ASSERT_BIT_CLEAR(reg, (1 << slot));
|
||||
}
|
||||
|
||||
/* And assert that we are generally not busy. */
|
||||
reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD);
|
||||
@@ -1207,9 +1260,10 @@ void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd)
|
||||
|
||||
#define RSET(REG, MASK) (BITSET(ahci_px_rreg(ahci, cmd->port, (REG)), (MASK)))
|
||||
|
||||
while (RSET(AHCI_PX_TFD, AHCI_PX_TFD_STS_BSY) ||
|
||||
RSET(AHCI_PX_CI, 1 << cmd->slot) ||
|
||||
(cmd->props->ncq && RSET(AHCI_PX_SACT, 1 << cmd->slot))) {
|
||||
while (!RSET(AHCI_PX_TFD, AHCI_PX_TFD_STS_ERR) &&
|
||||
(RSET(AHCI_PX_TFD, AHCI_PX_TFD_STS_BSY) ||
|
||||
RSET(AHCI_PX_CI, 1 << cmd->slot) ||
|
||||
(cmd->props->ncq && RSET(AHCI_PX_SACT, 1 << cmd->slot)))) {
|
||||
usleep(50);
|
||||
}
|
||||
|
||||
@@ -1226,9 +1280,9 @@ void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd)
|
||||
uint8_t slot = cmd->slot;
|
||||
uint8_t port = cmd->port;
|
||||
|
||||
ahci_port_check_error(ahci, port, cmd->interrupts, cmd->errors);
|
||||
ahci_port_check_interrupts(ahci, port, cmd->interrupts);
|
||||
ahci_port_check_nonbusy(ahci, port, slot);
|
||||
ahci_port_check_nonbusy(ahci, cmd);
|
||||
ahci_port_check_error(ahci, cmd);
|
||||
ahci_port_check_interrupts(ahci, cmd);
|
||||
ahci_port_check_cmd_sanity(ahci, cmd);
|
||||
if (cmd->interrupts & AHCI_PX_IS_DHRS) {
|
||||
ahci_port_check_d2h_sanity(ahci, port, slot);
|
||||
|
@@ -590,11 +590,9 @@ void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
|
||||
void ahci_destroy_command(AHCIQState *ahci, uint8_t port, uint8_t slot);
|
||||
|
||||
/* AHCI sanity check routines */
|
||||
void ahci_port_check_error(AHCIQState *ahci, uint8_t port,
|
||||
uint32_t imask, uint8_t emask);
|
||||
void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
|
||||
uint32_t intr_mask);
|
||||
void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot);
|
||||
void ahci_port_check_error(AHCIQState *ahci, AHCICommand *cmd);
|
||||
void ahci_port_check_interrupts(AHCIQState *ahci, AHCICommand *cmd);
|
||||
void ahci_port_check_nonbusy(AHCIQState *ahci, AHCICommand *cmd);
|
||||
void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot);
|
||||
void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd);
|
||||
void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd);
|
||||
|
@@ -45,9 +45,9 @@ static const char *hmp_cmds[] = {
|
||||
"log all",
|
||||
"log none",
|
||||
"memsave 0 4096 \"/dev/null\"",
|
||||
"migrate_set_parameter xbzrle_cache_size 1",
|
||||
"migrate_set_parameter downtime_limit 1",
|
||||
"migrate_set_parameter max_bandwidth 1",
|
||||
"migrate_set_parameter xbzrle-cache-size 1",
|
||||
"migrate_set_parameter downtime-limit 1",
|
||||
"migrate_set_parameter max-bandwidth 1",
|
||||
"netdev_add user,id=net1",
|
||||
"set_link net1 off",
|
||||
"set_link net1 on",
|
||||
|
@@ -1818,6 +1818,9 @@ bool dpy_ui_info_supported(QemuConsole *con)
|
||||
if (con == NULL) {
|
||||
con = active_console;
|
||||
}
|
||||
if (con == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return con->hw_ops->ui_info != NULL;
|
||||
}
|
||||
|
@@ -150,6 +150,8 @@ dbus_display_console_dispose(GObject *object)
|
||||
DBusDisplayConsole *ddc = DBUS_DISPLAY_CONSOLE(object);
|
||||
|
||||
unregister_displaychangelistener(&ddc->dcl);
|
||||
g_clear_object(&ddc->iface_touch);
|
||||
g_clear_object(&ddc->iface_mouse);
|
||||
g_clear_object(&ddc->iface_kbd);
|
||||
g_clear_object(&ddc->iface);
|
||||
g_clear_pointer(&ddc->listeners, g_hash_table_unref);
|
||||
|
Reference in New Issue
Block a user