278
279
static void amdvi_log_event(AMDVIState *s, uint64_t *evt)
280
{
281
+ uint64_t le_evt[2];
282
uint32_t evtlog_tail_next;
283
284
/* event logging not enabled */
299
return;
300
}
301
302
+ /*
303
+ * Convert event buffer to little-endian before writing it to guest memory.
304
+ */
305
+ le_evt[0] = cpu_to_le64(evt[0]);
306
+ le_evt[1] = cpu_to_le64(evt[1]);
307
+
308
if (dma_memory_write(&address_space_memory, s->evtlog + s->evtlog_tail,
302
- evt, AMDVI_EVENT_LEN, MEMTXATTRS_UNSPECIFIED)) {
309
+ le_evt, AMDVI_EVENT_LEN, MEMTXATTRS_UNSPECIFIED)) {
310
trace_amdvi_evntlog_fail(s->evtlog, s->evtlog_tail);
311
}
312
552
static void amdvi_completion_wait(AMDVIState *s, uint64_t *cmd)
553
{
554
/* pad the last 3 bits */
548
- hwaddr addr = cpu_to_le64(extract64(cmd[0], 3, 49)) << 3;
549
- uint64_t data = cpu_to_le64(cmd[1]);
555
+ hwaddr addr = extract64(cmd[0], 3, 49) << 3;
556
+ uint64_t data = cmd[1];
557
+
558
+ /* Format the data to be written to guest memory as little-endian */
559
+ uint64_t le_data = cpu_to_le64(data);
560
561
if (extract64(cmd[0], 52, 8)) {
562
amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
563
s->cmdbuf + s->cmdbuf_head);
564
}
565
if (extract64(cmd[0], 0, 1)) {
556
- if (dma_memory_write(&address_space_memory, addr, &data,
566
+ if (dma_memory_write(&address_space_memory, addr, &le_data,
567
AMDVI_COMPLETION_DATA_SIZE,
568
MEMTXATTRS_UNSPECIFIED)) {
569
trace_amdvi_completion_wait_fail(addr);
1291
/* log error without aborting since linux seems to be using reserved bits */
1292
static void amdvi_inval_devtab_entry(AMDVIState *s, uint64_t *cmd)
1293
{
1284
- uint16_t devid = cpu_to_le16((uint16_t)extract64(cmd[0], 0, 16));
1294
+ uint16_t devid = extract64(cmd[0], 0, 16);
1295
1296
trace_amdvi_devtab_inval(PCI_BUS_NUM(devid), PCI_SLOT(devid),
1297
PCI_FUNC(devid));
1458
/* we don't have devid - we can't remove pages by address */
1459
static void amdvi_inval_pages(AMDVIState *s, uint64_t *cmd)
1460
{
1451
- uint16_t domid = cpu_to_le16((uint16_t)extract64(cmd[0], 32, 16));
1452
- uint64_t addr = cpu_to_le64(extract64(cmd[1], 12, 52)) << 12;
1453
- uint16_t flags = cpu_to_le16((uint16_t)extract64(cmd[1], 0, 3));
1461
+ uint16_t domid = extract64(cmd[0], 32, 16);
1462
+ uint64_t addr = extract64(cmd[1], 12, 52) << 12;
1463
+ uint16_t flags = extract64(cmd[1], 0, 3);
1464
1465
if (extract64(cmd[0], 20, 12) || extract64(cmd[0], 48, 12) ||
1466
extract64(cmd[1], 3, 9)) {
1507
static void iommu_inval_iotlb(AMDVIState *s, uint64_t *cmd)
1508
{
1509
1500
- uint16_t devid = cpu_to_le16(extract64(cmd[0], 0, 16));
1510
+ uint16_t devid = extract64(cmd[0], 0, 16);
1511
if (extract64(cmd[1], 1, 1) || extract64(cmd[1], 3, 1) ||
1512
extract64(cmd[1], 6, 6)) {
1513
amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
1519
g_hash_table_foreach_remove(s->iotlb, amdvi_iotlb_remove_by_devid,
1520
&devid);
1521
} else {
1512
- amdvi_iotlb_remove_page(s, cpu_to_le64(extract64(cmd[1], 12, 52)) << 12,
1522
+ amdvi_iotlb_remove_page(s, extract64(cmd[1], 12, 52) << 12,
1523
devid);
1524
}
1525
trace_amdvi_iotlb_inval();
1537
return;
1538
}
1539
1540
+ /*
1541
+ * Commands in guest memory are little-endian. Convert once after reading
1542
+ * so that command handlers can decode values in host native endianness.
1543
+ * Convert back to little-endian only when writing data to guest memory via
1544
+ * dma_memory_write().
1545
+ */
1546
+ cmd[0] = le64_to_cpu(cmd[0]);
1547
+ cmd[1] = le64_to_cpu(cmd[1]);
1548
+
1549
switch (extract64(cmd[0], 60, 4)) {
1550
case AMDVI_CMD_COMPLETION_WAIT:
1551
amdvi_completion_wait(s, cmd);