From: @kuhnchen18 Reviewed-by: @imxcc Signed-off-by: @imxcc
This commit is contained in:
commit
6d95282b1e
33
block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch
Normal file
33
block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From d0586db311e8b78732923ce46f149fdf8251a59c Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 16:10:22 +0800
|
||||
Subject: [PATCH] block: bugfix: Don't pause vm when NOSPACE EIO happened
|
||||
|
||||
When backend disk is FULL and disk IO type is 'dataplane',
|
||||
QEMU will pause the vm, and this may cause endless-loop in
|
||||
QEMU main thread if we do the snapshot merge now.
|
||||
|
||||
When backend disk is FULL, only reporting an error rather
|
||||
than pausing the virtual machine.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
blockdev.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 37e3ee6f26..3ce294ec4a 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -556,7 +556,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
qdict_put_str(bs_opts, "driver", buf);
|
||||
}
|
||||
|
||||
- on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
|
||||
+ on_write_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
|
||||
on_write_error = parse_block_error_action(buf, 0, &error);
|
||||
if (error) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
43
block-bugfix-disable-process-AIO-when-attach-scsi-di.patch
Normal file
43
block-bugfix-disable-process-AIO-when-attach-scsi-di.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 87d8b7dcd880e0cef0c043dfef5ae649652cfe21 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 11:51:43 +0800
|
||||
Subject: [PATCH] block: bugfix: disable process AIO when attach scsi disk
|
||||
|
||||
When initializing the virtio-scsi disk, hd_geometry_guess() will
|
||||
be called to process AIO. At this time, the scsi disk has not
|
||||
been fully initialized, and some fields in struct SCSIDiskState,
|
||||
such as vendor and version, are NULL. If processing AIO at this
|
||||
time, qemu may crash down.
|
||||
|
||||
Add aio_disable_external() before hd_geometry_guess() to disable
|
||||
processing AIO at that time.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
hw/block/block.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/hw/block/block.c b/hw/block/block.c
|
||||
index 26c0767552..2cfc93a68e 100644
|
||||
--- a/hw/block/block.c
|
||||
+++ b/hw/block/block.c
|
||||
@@ -224,9 +224,16 @@ bool blkconf_geometry(BlockConf *conf, int *ptrans,
|
||||
Error **errp)
|
||||
{
|
||||
if (!conf->cyls && !conf->heads && !conf->secs) {
|
||||
+ AioContext *ctx = blk_get_aio_context(conf->blk);
|
||||
+
|
||||
+ /* Callers may not expect this function to dispatch aio handlers, so
|
||||
+ * disable external aio such as guest device emulation.
|
||||
+ */
|
||||
+ aio_disable_external(ctx);
|
||||
hd_geometry_guess(conf->blk,
|
||||
&conf->cyls, &conf->heads, &conf->secs,
|
||||
ptrans);
|
||||
+ aio_enable_external(ctx);
|
||||
} else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
|
||||
*ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
47
block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch
Normal file
47
block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 0a2c96ee5a3463e82397afb9cb36f340a93264c2 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 11:29:15 +0800
|
||||
Subject: [PATCH] block: disallow block jobs when there is a BDRV_O_INACTIVE
|
||||
flag
|
||||
|
||||
Currently, migration will put a BDRV_O_INACTIVE flag
|
||||
on bs's open_flags until another resume being called. In that case,
|
||||
any IO from vm or block jobs will cause a qemu crash with an assert
|
||||
'assert(!(bs->open_flags & BDRV_O_INACTIVE))' failure in bdrv_co_pwritev
|
||||
function. we hereby disallow block jobs by faking a blocker.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
block.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/block.c b/block.c
|
||||
index 0ac5b163d2..26c3982567 100644
|
||||
--- a/block.c
|
||||
+++ b/block.c
|
||||
@@ -6692,6 +6692,22 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * When migration puts a BDRV_O_INACTIVE flag on driver's open_flags,
|
||||
+ * we fake a blocker that doesn't exist. From now on, block jobs
|
||||
+ * will not be permitted.
|
||||
+ */
|
||||
+ if ((op == BLOCK_OP_TYPE_RESIZE || op == BLOCK_OP_TYPE_COMMIT_SOURCE ||
|
||||
+ op == BLOCK_OP_TYPE_MIRROR_SOURCE || op == BLOCK_OP_TYPE_MIRROR_TARGET) &&
|
||||
+ (bs->open_flags & BDRV_O_INACTIVE)) {
|
||||
+ if (errp) {
|
||||
+ error_setg(errp, "block device is in use by migration with"
|
||||
+ " a driver BDRV_O_INACTIVE flag setted");
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
return false;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
49
block-enable-cache-mode-of-empty-cdrom.patch
Normal file
49
block-enable-cache-mode-of-empty-cdrom.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 21b172a3ce13c3b499e4265628f7d7c7e1189749 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 11:18:21 +0800
|
||||
Subject: [PATCH] block: enable cache mode of empty cdrom
|
||||
|
||||
enable cache mode even if cdrom is empty
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
blockdev.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 10a73fa423..37e3ee6f26 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -492,6 +492,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
QDict *interval_dict = NULL;
|
||||
QList *interval_list = NULL;
|
||||
const char *id;
|
||||
+ const char *cache;
|
||||
BlockdevDetectZeroesOptions detect_zeroes =
|
||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
|
||||
const char *throttling_group = NULL;
|
||||
@@ -583,6 +584,21 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
|
||||
read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
|
||||
|
||||
+ if (!file || !*file) {
|
||||
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
+ if (cache && !strcmp(cache, "on")) {
|
||||
+ bdrv_flags |= BDRV_O_NO_FLUSH;
|
||||
+ }
|
||||
+
|
||||
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_DIRECT);
|
||||
+ if (cache && !strcmp(cache, "on")) {
|
||||
+ bdrv_flags |= BDRV_O_NOCACHE;
|
||||
+ }
|
||||
+
|
||||
+ qdict_del(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
+ qdict_del(bs_opts, BDRV_OPT_CACHE_DIRECT);
|
||||
+ }
|
||||
+
|
||||
/* init */
|
||||
if ((!file || !*file) && !qdict_size(bs_opts)) {
|
||||
BlockBackendRootState *blk_rs;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
125
freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch
Normal file
125
freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 124d427a1fdae2d1eeed433093ec4ab78b81237e Mon Sep 17 00:00:00 2001
|
||||
From: "shenghualong@huawei.com" <shenghualong@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 11:11:37 +0800
|
||||
Subject: [PATCH] freeclock: add qmp command to get time offset of vm in
|
||||
seconds
|
||||
|
||||
When setting the system time in VM, a RTC_CHANGE event will be reported.
|
||||
However, if libvirt is restarted while the event is be reporting, the
|
||||
event will be lost and we will get the old time (not the time we set in
|
||||
VM) after rebooting the VM.
|
||||
|
||||
We save the delta time in QEMU and add a rtc-date-diff qmp to get the
|
||||
delta time so that libvirt can get the latest time in VM according to
|
||||
the qmp after libvirt is restarted.
|
||||
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
|
||||
---
|
||||
include/qemu-common.h | 4 +++-
|
||||
monitor/qmp-cmds.c | 5 +++++
|
||||
qapi/misc.json | 9 +++++++++
|
||||
qapi/pragma.json | 3 ++-
|
||||
softmmu/rtc.c | 13 ++++++++++++-
|
||||
5 files changed, 31 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/qemu-common.h b/include/qemu-common.h
|
||||
index 73bcf763ed..9ed8832152 100644
|
||||
--- a/include/qemu-common.h
|
||||
+++ b/include/qemu-common.h
|
||||
@@ -27,7 +27,9 @@ int qemu_main(int argc, char **argv, char **envp);
|
||||
#endif
|
||||
|
||||
void qemu_get_timedate(struct tm *tm, int offset);
|
||||
-int qemu_timedate_diff(struct tm *tm);
|
||||
+time_t qemu_timedate_diff(struct tm *tm);
|
||||
+time_t get_rtc_date_diff(void);
|
||||
+void set_rtc_date_diff(time_t diff);
|
||||
|
||||
void *qemu_oom_check(void *ptr);
|
||||
|
||||
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
|
||||
index 343353e27a..98868cee03 100644
|
||||
--- a/monitor/qmp-cmds.c
|
||||
+++ b/monitor/qmp-cmds.c
|
||||
@@ -466,3 +466,8 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
|
||||
|
||||
return human_readable_text_from_str(buf);
|
||||
}
|
||||
+
|
||||
+int64_t qmp_query_rtc_date_diff(Error **errp)
|
||||
+{
|
||||
+ return get_rtc_date_diff();
|
||||
+}
|
||||
diff --git a/qapi/misc.json b/qapi/misc.json
|
||||
index 358548abe1..5b6d653682 100644
|
||||
--- a/qapi/misc.json
|
||||
+++ b/qapi/misc.json
|
||||
@@ -527,3 +527,12 @@
|
||||
'data': { '*option': 'str' },
|
||||
'returns': ['CommandLineOptionInfo'],
|
||||
'allow-preconfig': true }
|
||||
+
|
||||
+##
|
||||
+# @query-rtc-date-diff:
|
||||
+#
|
||||
+# get vm's time offset
|
||||
+#
|
||||
+# Since: 2.8
|
||||
+##
|
||||
+{ 'command': 'query-rtc-date-diff', 'returns': 'int64' }
|
||||
diff --git a/qapi/pragma.json b/qapi/pragma.json
|
||||
index 3bc0335d1f..b37f6de445 100644
|
||||
--- a/qapi/pragma.json
|
||||
+++ b/qapi/pragma.json
|
||||
@@ -26,7 +26,8 @@
|
||||
'qom-get',
|
||||
'query-tpm-models',
|
||||
'query-tpm-types',
|
||||
- 'ringbuf-read' ],
|
||||
+ 'ringbuf-read',
|
||||
+ 'query-rtc-date-diff' ],
|
||||
# Externally visible types whose member names may use uppercase
|
||||
'member-name-exceptions': [ # visible in:
|
||||
'ACPISlotType', # query-acpi-ospm-status
|
||||
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
|
||||
index 5632684fc9..57bb8bba7c 100644
|
||||
--- a/softmmu/rtc.c
|
||||
+++ b/softmmu/rtc.c
|
||||
@@ -43,6 +43,7 @@ static time_t rtc_ref_start_datetime;
|
||||
static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
|
||||
static int rtc_host_datetime_offset = -1; /* valid & used only with
|
||||
RTC_BASE_DATETIME */
|
||||
+static time_t rtc_date_diff = 0;
|
||||
QEMUClockType rtc_clock;
|
||||
/***********************************************************/
|
||||
/* RTC reference time/date access */
|
||||
@@ -84,7 +85,7 @@ void qemu_get_timedate(struct tm *tm, int offset)
|
||||
}
|
||||
}
|
||||
|
||||
-int qemu_timedate_diff(struct tm *tm)
|
||||
+time_t qemu_timedate_diff(struct tm *tm)
|
||||
{
|
||||
time_t seconds;
|
||||
|
||||
@@ -107,6 +108,16 @@ int qemu_timedate_diff(struct tm *tm)
|
||||
return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
|
||||
}
|
||||
|
||||
+time_t get_rtc_date_diff(void)
|
||||
+{
|
||||
+ return rtc_date_diff;
|
||||
+}
|
||||
+
|
||||
+void set_rtc_date_diff(time_t diff)
|
||||
+{
|
||||
+ rtc_date_diff = diff;
|
||||
+}
|
||||
+
|
||||
static void configure_rtc_base_datetime(const char *startdate)
|
||||
{
|
||||
time_t rtc_start_datetime;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
30
freeclock-set-rtc_date_diff-for-X86.patch
Normal file
30
freeclock-set-rtc_date_diff-for-X86.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 3d0846d864384be3d08a54ca6e2ce247a5cee952 Mon Sep 17 00:00:00 2001
|
||||
From: l00500761 <liuxiangdong5@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 14:25:30 +0800
|
||||
Subject: [PATCH] freeclock: set rtc_date_diff for X86
|
||||
|
||||
Set rtc_date_diff in mc146818rtc.
|
||||
|
||||
Signed-off-by: l00500761 <liuxiangdong5@huawei.com>
|
||||
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
|
||||
---
|
||||
hw/rtc/mc146818rtc.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
|
||||
index 4fbafddb22..af1df9aaeb 100644
|
||||
--- a/hw/rtc/mc146818rtc.c
|
||||
+++ b/hw/rtc/mc146818rtc.c
|
||||
@@ -616,7 +616,8 @@ static void rtc_set_time(RTCState *s)
|
||||
s->base_rtc = mktimegm(&tm);
|
||||
s->last_update = qemu_clock_get_ns(rtc_clock);
|
||||
|
||||
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
|
||||
+ set_rtc_date_diff(qemu_timedate_diff(&tm));
|
||||
+ qapi_event_send_rtc_change(get_rtc_date_diff());
|
||||
}
|
||||
|
||||
static void rtc_set_cmos(RTCState *s, const struct tm *tm)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
30
freeclock-set-rtc_date_diff-for-arm.patch
Normal file
30
freeclock-set-rtc_date_diff-for-arm.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 1e6bae1d13302594b6e63d88e8627fa477966cf4 Mon Sep 17 00:00:00 2001
|
||||
From: "shenghualong@huawei.com" <shenghualong@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 14:23:28 +0800
|
||||
Subject: [PATCH] freeclock: set rtc_date_diff for arm
|
||||
|
||||
Set rtc_date_diff in pl031.
|
||||
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
|
||||
---
|
||||
hw/rtc/pl031.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
|
||||
index e7ced90b02..da8b061e91 100644
|
||||
--- a/hw/rtc/pl031.c
|
||||
+++ b/hw/rtc/pl031.c
|
||||
@@ -143,7 +143,8 @@ static void pl031_write(void * opaque, hwaddr offset,
|
||||
s->tick_offset += value - pl031_get_count(s);
|
||||
|
||||
qemu_get_timedate(&tm, s->tick_offset);
|
||||
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
|
||||
+ set_rtc_date_diff(qemu_timedate_diff(&tm));
|
||||
+ qapi_event_send_rtc_change(get_rtc_date_diff());
|
||||
|
||||
pl031_set_alarm(s);
|
||||
break;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
28
hw-net-rocker-fix-security-vulnerability.patch
Normal file
28
hw-net-rocker-fix-security-vulnerability.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 9a8de722b047ba66f70e87fb29b877935c187457 Mon Sep 17 00:00:00 2001
|
||||
From: Lichang Zhao <zhaolichang@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 16:54:06 +0800
|
||||
Subject: [PATCH] hw/net/rocker: fix security vulnerability
|
||||
|
||||
fix security vulnerability
|
||||
|
||||
Signed-off-by: Lichang zhao <zhaolichang@huawei.com>
|
||||
Signed-off-by: Jinhao Gao <gaojinhao@huawei.com>
|
||||
---
|
||||
hw/net/rocker/rocker_of_dpa.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
|
||||
index b3b8c5bb6d..8ac26e6beb 100644
|
||||
--- a/hw/net/rocker/rocker_of_dpa.c
|
||||
+++ b/hw/net/rocker/rocker_of_dpa.c
|
||||
@@ -2070,6 +2070,7 @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
|
||||
err_out:
|
||||
group->l2_flood.group_count = 0;
|
||||
g_free(group->l2_flood.group_ids);
|
||||
+ group->l2_flood.group_ids = NULL;
|
||||
g_free(tlvs);
|
||||
|
||||
return err;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
459
hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch
Normal file
459
hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch
Normal file
@ -0,0 +1,459 @@
|
||||
From 93f01916f0c1e11f38edb8ccc4118c940d9c089f Mon Sep 17 00:00:00 2001
|
||||
From: eillon <yezhenyu2@huawei.com>
|
||||
Date: Tue, 8 Feb 2022 22:43:59 -0500
|
||||
Subject: [PATCH] hw/usb: reduce the vpcu cost of UHCI when VNC disconnect
|
||||
|
||||
Reduce the vpcu cost by set a lower FRAME_TIMER_FREQ of the UHCI
|
||||
when VNC client disconnected. This can reduce about 3% cost of
|
||||
vcpu thread.
|
||||
|
||||
Signed-off-by: eillon <yezhenyu2@huawei.com>
|
||||
---
|
||||
hw/usb/core.c | 5 ++--
|
||||
hw/usb/desc.c | 7 +++--
|
||||
hw/usb/dev-hid.c | 2 +-
|
||||
hw/usb/hcd-uhci.c | 63 ++++++++++++++++++++++++++++++++++------
|
||||
hw/usb/hcd-uhci.h | 1 +
|
||||
hw/usb/host-libusb.c | 32 ++++++++++++++++++++
|
||||
include/hw/usb.h | 1 +
|
||||
include/qemu/timer.h | 28 ++++++++++++++++++
|
||||
ui/vnc.c | 4 +++
|
||||
util/qemu-timer.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
10 files changed, 197 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/hw/usb/core.c b/hw/usb/core.c
|
||||
index 975f76250a..51b36126ca 100644
|
||||
--- a/hw/usb/core.c
|
||||
+++ b/hw/usb/core.c
|
||||
@@ -87,7 +87,7 @@ void usb_device_reset(USBDevice *dev)
|
||||
return;
|
||||
}
|
||||
usb_device_handle_reset(dev);
|
||||
- dev->remote_wakeup = 0;
|
||||
+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP;
|
||||
dev->addr = 0;
|
||||
dev->state = USB_STATE_DEFAULT;
|
||||
}
|
||||
@@ -105,7 +105,8 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
- if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
|
||||
+ if ((dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP)
|
||||
+ && dev->port && dev->port->ops->wakeup) {
|
||||
dev->port->ops->wakeup(dev->port);
|
||||
}
|
||||
if (bus->ops->wakeup_endpoint) {
|
||||
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
|
||||
index 8b6eaea407..78bbe74c71 100644
|
||||
--- a/hw/usb/desc.c
|
||||
+++ b/hw/usb/desc.c
|
||||
@@ -751,7 +751,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||
if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) {
|
||||
data[0] |= 1 << USB_DEVICE_SELF_POWERED;
|
||||
}
|
||||
- if (dev->remote_wakeup) {
|
||||
+ if (dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) {
|
||||
data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP;
|
||||
}
|
||||
data[1] = 0x00;
|
||||
@@ -761,14 +761,15 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||
}
|
||||
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
|
||||
if (value == USB_DEVICE_REMOTE_WAKEUP) {
|
||||
- dev->remote_wakeup = 0;
|
||||
+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP;
|
||||
ret = 0;
|
||||
}
|
||||
trace_usb_clear_device_feature(dev->addr, value, ret);
|
||||
break;
|
||||
case DeviceOutRequest | USB_REQ_SET_FEATURE:
|
||||
+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED;
|
||||
if (value == USB_DEVICE_REMOTE_WAKEUP) {
|
||||
- dev->remote_wakeup = 1;
|
||||
+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP;
|
||||
ret = 0;
|
||||
}
|
||||
trace_usb_set_device_feature(dev->addr, value, ret);
|
||||
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
|
||||
index 1c7ae97c30..9fb89f6955 100644
|
||||
--- a/hw/usb/dev-hid.c
|
||||
+++ b/hw/usb/dev-hid.c
|
||||
@@ -745,7 +745,7 @@ static int usb_ptr_post_load(void *opaque, int version_id)
|
||||
{
|
||||
USBHIDState *s = opaque;
|
||||
|
||||
- if (s->dev.remote_wakeup) {
|
||||
+ if (s->dev.remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) {
|
||||
hid_pointer_activate(&s->hid);
|
||||
}
|
||||
return 0;
|
||||
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
|
||||
index d1b5657d72..693c68f445 100644
|
||||
--- a/hw/usb/hcd-uhci.c
|
||||
+++ b/hw/usb/hcd-uhci.c
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "hcd-uhci.h"
|
||||
|
||||
#define FRAME_TIMER_FREQ 1000
|
||||
+#define FRAME_TIMER_FREQ_LAZY 10
|
||||
+#define USB_DEVICE_NEED_NORMAL_FREQ "QEMU USB Tablet"
|
||||
|
||||
#define FRAME_MAX_LOOPS 256
|
||||
|
||||
@@ -111,6 +113,22 @@ static void uhci_async_cancel(UHCIAsync *async);
|
||||
static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
|
||||
static void uhci_resume(void *opaque);
|
||||
|
||||
+static int64_t uhci_frame_timer_freq = FRAME_TIMER_FREQ_LAZY;
|
||||
+
|
||||
+static void uhci_set_frame_freq(int freq)
|
||||
+{
|
||||
+ if (freq <= 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ uhci_frame_timer_freq = freq;
|
||||
+}
|
||||
+
|
||||
+static qemu_usb_controller qemu_uhci = {
|
||||
+ .name = "uhci",
|
||||
+ .qemu_set_freq = uhci_set_frame_freq,
|
||||
+};
|
||||
+
|
||||
static inline int32_t uhci_queue_token(UHCI_TD *td)
|
||||
{
|
||||
if ((td->token & (0xf << 15)) == 0) {
|
||||
@@ -353,7 +371,7 @@ static int uhci_post_load(void *opaque, int version_id)
|
||||
|
||||
if (version_id < 2) {
|
||||
s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||
- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ);
|
||||
+ (NANOSECONDS_PER_SECOND / uhci_frame_timer_freq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -394,8 +412,29 @@ static void uhci_port_write(void *opaque, hwaddr addr,
|
||||
if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
|
||||
/* start frame processing */
|
||||
trace_usb_uhci_schedule_start();
|
||||
- s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||
- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ);
|
||||
+
|
||||
+ /*
|
||||
+ * If the frequency of frame_timer is too slow, Guest OS (Win2012) would become
|
||||
+ * blue-screen after hotplugging some vcpus.
|
||||
+ * If this USB device support the remote-wakeup, the UHCI controller
|
||||
+ * will enter global suspend mode when there is no input for several seconds.
|
||||
+ * In this case, Qemu will delete the frame_timer. Since the frame_timer has been deleted,
|
||||
+ * there is no influence to the performance of Vms. So, we can change the frequency to 1000.
|
||||
+ * After that the frequency will be safe when we trigger the frame_timer again.
|
||||
+ * Excepting this, there are two ways to change the frequency:
|
||||
+ * 1)VNC connect/disconnect;2)attach/detach USB device.
|
||||
+ */
|
||||
+ if ((uhci_frame_timer_freq != FRAME_TIMER_FREQ)
|
||||
+ && (s->ports[0].port.dev)
|
||||
+ && (!memcmp(s->ports[0].port.dev->product_desc,
|
||||
+ USB_DEVICE_NEED_NORMAL_FREQ, strlen(USB_DEVICE_NEED_NORMAL_FREQ)))
|
||||
+ && (s->ports[0].port.dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED)) {
|
||||
+ qemu_log("turn up the frequency of UHCI controller to %d\n", FRAME_TIMER_FREQ);
|
||||
+ uhci_frame_timer_freq = FRAME_TIMER_FREQ;
|
||||
+ }
|
||||
+
|
||||
+ s->frame_time = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ;
|
||||
+ s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->frame_time;
|
||||
timer_mod(s->frame_timer, s->expire_time);
|
||||
s->status &= ~UHCI_STS_HCHALTED;
|
||||
} else if (!(val & UHCI_CMD_RS)) {
|
||||
@@ -1083,7 +1122,6 @@ static void uhci_frame_timer(void *opaque)
|
||||
UHCIState *s = opaque;
|
||||
uint64_t t_now, t_last_run;
|
||||
int i, frames;
|
||||
- const uint64_t frame_t = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ;
|
||||
|
||||
s->completions_only = false;
|
||||
qemu_bh_cancel(s->bh);
|
||||
@@ -1099,14 +1137,14 @@ static void uhci_frame_timer(void *opaque)
|
||||
}
|
||||
|
||||
/* We still store expire_time in our state, for migration */
|
||||
- t_last_run = s->expire_time - frame_t;
|
||||
+ t_last_run = s->expire_time - s->frame_time;
|
||||
t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
|
||||
/* Process up to MAX_FRAMES_PER_TICK frames */
|
||||
- frames = (t_now - t_last_run) / frame_t;
|
||||
+ frames = (t_now - t_last_run) / s->frame_time;
|
||||
if (frames > s->maxframes) {
|
||||
int skipped = frames - s->maxframes;
|
||||
- s->expire_time += skipped * frame_t;
|
||||
+ s->expire_time += skipped * s->frame_time;
|
||||
s->frnum = (s->frnum + skipped) & 0x7ff;
|
||||
frames -= skipped;
|
||||
}
|
||||
@@ -1123,7 +1161,7 @@ static void uhci_frame_timer(void *opaque)
|
||||
/* The spec says frnum is the frame currently being processed, and
|
||||
* the guest must look at frnum - 1 on interrupt, so inc frnum now */
|
||||
s->frnum = (s->frnum + 1) & 0x7ff;
|
||||
- s->expire_time += frame_t;
|
||||
+ s->expire_time += s->frame_time;
|
||||
}
|
||||
|
||||
/* Complete the previous frame(s) */
|
||||
@@ -1134,7 +1172,12 @@ static void uhci_frame_timer(void *opaque)
|
||||
}
|
||||
s->pending_int_mask = 0;
|
||||
|
||||
- timer_mod(s->frame_timer, t_now + frame_t);
|
||||
+ /* expire_time is calculated from last frame_time, we should calculate it
|
||||
+ * according to new frame_time which equals to
|
||||
+ * NANOSECONDS_PER_SECOND / uhci_frame_timer_freq */
|
||||
+ s->expire_time -= s->frame_time - NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
|
||||
+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
|
||||
+ timer_mod(s->frame_timer, t_now + s->frame_time);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps uhci_ioport_ops = {
|
||||
@@ -1196,8 +1239,10 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
|
||||
s->bh = qemu_bh_new(uhci_bh, s);
|
||||
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
|
||||
s->num_ports_vmstate = NB_PORTS;
|
||||
+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
|
||||
QTAILQ_INIT(&s->queues);
|
||||
|
||||
+ qemu_register_usb_controller(&qemu_uhci, QEMU_USB_CONTROLLER_UHCI);
|
||||
memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
|
||||
"uhci", 0x20);
|
||||
|
||||
diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h
|
||||
index c85ab7868e..5194d22ab4 100644
|
||||
--- a/hw/usb/hcd-uhci.h
|
||||
+++ b/hw/usb/hcd-uhci.h
|
||||
@@ -50,6 +50,7 @@ typedef struct UHCIState {
|
||||
uint16_t status;
|
||||
uint16_t intr; /* interrupt enable register */
|
||||
uint16_t frnum; /* frame number */
|
||||
+ uint64_t frame_time; /* frame time in ns */
|
||||
uint32_t fl_base_addr; /* frame list base address */
|
||||
uint8_t sof_timing;
|
||||
uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
|
||||
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
|
||||
index d0d46dd0a4..8f521ad586 100644
|
||||
--- a/hw/usb/host-libusb.c
|
||||
+++ b/hw/usb/host-libusb.c
|
||||
@@ -945,6 +945,30 @@ static void usb_host_ep_update(USBHostDevice *s)
|
||||
libusb_free_config_descriptor(conf);
|
||||
}
|
||||
|
||||
+static unsigned int usb_get_controller_type(int speed)
|
||||
+{
|
||||
+ unsigned int type = MAX_USB_CONTROLLER_TYPES;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case USB_SPEED_SUPER:
|
||||
+ type = QEMU_USB_CONTROLLER_XHCI;
|
||||
+ break;
|
||||
+ case USB_SPEED_HIGH:
|
||||
+ type = QEMU_USB_CONTROLLER_EHCI;
|
||||
+ break;
|
||||
+ case USB_SPEED_FULL:
|
||||
+ type = QEMU_USB_CONTROLLER_UHCI;
|
||||
+ break;
|
||||
+ case USB_SPEED_LOW:
|
||||
+ type = QEMU_USB_CONTROLLER_OHCI;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return type;
|
||||
+}
|
||||
+
|
||||
static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
|
||||
{
|
||||
USBDevice *udev = USB_DEVICE(s);
|
||||
@@ -1054,6 +1078,12 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
|
||||
}
|
||||
|
||||
trace_usb_host_open_success(bus_num, addr);
|
||||
+
|
||||
+ /* change ehci frame time freq when USB passthrough */
|
||||
+ qemu_log("usb host speed is %d\n", udev->speed);
|
||||
+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE,
|
||||
+ usb_get_controller_type(udev->speed));
|
||||
+
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@@ -1129,6 +1159,8 @@ static int usb_host_close(USBHostDevice *s)
|
||||
}
|
||||
|
||||
usb_host_auto_check(NULL);
|
||||
+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE,
|
||||
+ usb_get_controller_type(udev->speed));
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/hw/usb.h b/include/hw/usb.h
|
||||
index 33668dd0a9..fa3a176159 100644
|
||||
--- a/include/hw/usb.h
|
||||
+++ b/include/hw/usb.h
|
||||
@@ -142,6 +142,7 @@
|
||||
|
||||
#define USB_DEVICE_SELF_POWERED 0
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1
|
||||
+#define USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED 2
|
||||
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
|
||||
index 88ef114689..d263fad9a4 100644
|
||||
--- a/include/qemu/timer.h
|
||||
+++ b/include/qemu/timer.h
|
||||
@@ -91,6 +91,34 @@ struct QEMUTimer {
|
||||
int scale;
|
||||
};
|
||||
|
||||
+#define QEMU_USB_NORMAL_FREQ 1000
|
||||
+#define QEMU_USB_LAZY_FREQ 10
|
||||
+#define MAX_USB_CONTROLLER_TYPES 4
|
||||
+#define QEMU_USB_CONTROLLER_OHCI 0
|
||||
+#define QEMU_USB_CONTROLLER_UHCI 1
|
||||
+#define QEMU_USB_CONTROLLER_EHCI 2
|
||||
+#define QEMU_USB_CONTROLLER_XHCI 3
|
||||
+
|
||||
+typedef void (*QEMUSetFreqHandler) (int freq);
|
||||
+
|
||||
+typedef struct qemu_usb_controller {
|
||||
+ const char *name;
|
||||
+ QEMUSetFreqHandler qemu_set_freq;
|
||||
+} qemu_usb_controller;
|
||||
+
|
||||
+typedef qemu_usb_controller* qemu_usb_controller_ptr;
|
||||
+
|
||||
+enum qemu_timer_mode {
|
||||
+ QEMU_TIMER_USB_NORMAL_MODE = 1 << 0, /* Set when VNC connect or
|
||||
+ * with usb dev passthrough
|
||||
+ */
|
||||
+ QEMU_TIMER_USB_LAZY_MODE = 1 << 1, /* Set when VNC disconnect */
|
||||
+};
|
||||
+
|
||||
+int qemu_register_usb_controller(qemu_usb_controller_ptr controller,
|
||||
+ unsigned int type);
|
||||
+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type);
|
||||
+
|
||||
extern QEMUTimerListGroup main_loop_tlg;
|
||||
|
||||
/*
|
||||
diff --git a/ui/vnc.c b/ui/vnc.c
|
||||
index af02522e84..bc86c20370 100644
|
||||
--- a/ui/vnc.c
|
||||
+++ b/ui/vnc.c
|
||||
@@ -1379,6 +1379,8 @@ void vnc_disconnect_finish(VncState *vs)
|
||||
g_free(vs->zrle);
|
||||
g_free(vs->tight);
|
||||
g_free(vs);
|
||||
+
|
||||
+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE, QEMU_USB_CONTROLLER_UHCI);
|
||||
}
|
||||
|
||||
size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
|
||||
@@ -3333,6 +3335,8 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE, QEMU_USB_CONTROLLER_UHCI);
|
||||
}
|
||||
|
||||
void vnc_start_protocol(VncState *vs)
|
||||
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
|
||||
index f36c75e594..40e8c83722 100644
|
||||
--- a/util/qemu-timer.c
|
||||
+++ b/util/qemu-timer.c
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
+#include "qemu/log.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/lockable.h"
|
||||
@@ -75,6 +76,74 @@ struct QEMUTimerList {
|
||||
QemuEvent timers_done_ev;
|
||||
};
|
||||
|
||||
+typedef struct qemu_controller_timer_state {
|
||||
+ qemu_usb_controller_ptr controller;
|
||||
+ int refs;
|
||||
+} controller_timer_state;
|
||||
+
|
||||
+typedef controller_timer_state* controller_timer_state_ptr;
|
||||
+
|
||||
+static controller_timer_state uhci_timer_state = {
|
||||
+ .controller = NULL,
|
||||
+ .refs = 0,
|
||||
+};
|
||||
+
|
||||
+static controller_timer_state_ptr \
|
||||
+ qemu_usb_controller_tab[MAX_USB_CONTROLLER_TYPES] = {NULL,
|
||||
+ &uhci_timer_state,
|
||||
+ NULL, NULL};
|
||||
+
|
||||
+int qemu_register_usb_controller(qemu_usb_controller_ptr controller,
|
||||
+ unsigned int type)
|
||||
+{
|
||||
+ if (type != QEMU_USB_CONTROLLER_UHCI) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* for companion EHCI controller will create three UHCI controllers,
|
||||
+ * we init it only once.
|
||||
+ */
|
||||
+ if (!qemu_usb_controller_tab[type]->controller) {
|
||||
+ qemu_log("the usb controller (%d) registed frame handler\n", type);
|
||||
+ qemu_usb_controller_tab[type]->controller = controller;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type)
|
||||
+{
|
||||
+ if (type != QEMU_USB_CONTROLLER_UHCI) {
|
||||
+ qemu_log("the usb controller (%d) no need change frame frep\n", type);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!qemu_usb_controller_tab[type]->controller) {
|
||||
+ qemu_log("the usb controller (%d) not registed yet\n", type);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (mode == QEMU_TIMER_USB_NORMAL_MODE) {
|
||||
+ if (qemu_usb_controller_tab[type]->refs++ > 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ qemu_usb_controller_tab[type]->controller->
|
||||
+ qemu_set_freq(QEMU_USB_NORMAL_FREQ);
|
||||
+ qemu_log("Set the controller (%d) of freq %d HZ,\n",
|
||||
+ type, QEMU_USB_NORMAL_FREQ);
|
||||
+ } else {
|
||||
+ if (--qemu_usb_controller_tab[type]->refs > 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ qemu_usb_controller_tab[type]->controller->
|
||||
+ qemu_set_freq(QEMU_USB_LAZY_FREQ);
|
||||
+ qemu_log("Set the controller(type:%d) of freq %d HZ,\n",
|
||||
+ type, QEMU_USB_LAZY_FREQ);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* qemu_clock_ptr:
|
||||
* @type: type of clock
|
||||
--
|
||||
2.27.0
|
||||
|
||||
64
i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch
Normal file
64
i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 475988057789a1f4dcd7354c8a07fd37dcbac79f Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 20:06:01 +0800
|
||||
Subject: [PATCH] i386: cache passthrough: Update AMD 8000_001D.EAX[25:14]
|
||||
based on vCPU topo
|
||||
|
||||
On AMD target, when host cache passthrough is disabled we will
|
||||
emulate the guest caches with default values and initialize the
|
||||
shared cpu list of the caches based on vCPU topology. However
|
||||
when host cache passthrough is enabled, the shared cpu list is
|
||||
consistent with host regardless what the vCPU topology is.
|
||||
|
||||
For example, when cache passthrough is enabled, running a guest
|
||||
with vThreads=1 on a host with pThreads=2, we will get that there
|
||||
are every *two* logical vCPUs sharing a L1/L2 cache, which is not
|
||||
consistent with the vCPU topology (vThreads=1).
|
||||
|
||||
So let's reinitialize BITs[25:14] of AMD CPUID 8000_001D.EAX
|
||||
based on the actual vCPU topology instead of host pCPU topology.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
---
|
||||
target/i386/cpu.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index c1fe2895fd..002e32650d 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -5724,9 +5724,31 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
}
|
||||
break;
|
||||
case 0x8000001D:
|
||||
+ /* Populate AMD Processor Cache Information */
|
||||
*eax = 0;
|
||||
if (cpu->cache_info_passthrough) {
|
||||
host_cpuid(index, count, eax, ebx, ecx, edx);
|
||||
+
|
||||
+ /*
|
||||
+ * Clear BITs[25:14] and then update them based on the guest
|
||||
+ * vCPU topology, like what we do in encode_cache_cpuid8000001d
|
||||
+ * when cache_info_passthrough is not enabled.
|
||||
+ */
|
||||
+ *eax &= ~0x03FFC000;
|
||||
+ switch (count) {
|
||||
+ case 0: /* L1 dcache info */
|
||||
+ case 1: /* L1 icache info */
|
||||
+ case 2: /* L2 cache info */
|
||||
+ *eax |= ((topo_info.threads_per_core - 1) << 14);
|
||||
+ break;
|
||||
+ case 3: /* L3 cache info */
|
||||
+ *eax |= ((topo_info.cores_per_die *
|
||||
+ topo_info.threads_per_core - 1) << 14);
|
||||
+ break;
|
||||
+ default: /* end of info */
|
||||
+ *eax = *ebx = *ecx = *edx = 0;
|
||||
+ break;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
switch (count) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
88
i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch
Normal file
88
i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 3eaa433ca1cbee753698893b7732819ba2e31302 Mon Sep 17 00:00:00 2001
|
||||
From: Jian Wang <wangjian161@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 19:43:55 +0800
|
||||
Subject: [PATCH] i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based
|
||||
on vCPU topo
|
||||
|
||||
On Intel target, when host cache passthrough is disabled we will
|
||||
emulate the guest caches with default values and initialize the
|
||||
shared cpu list of the caches based on vCPU topology. However when
|
||||
host cache passthrough is enabled, the shared cpu list is consistent
|
||||
with host regardless what the vCPU topology is.
|
||||
|
||||
For example, when cache passthrough is enabled, running a guest
|
||||
with vThreads=1 on a host with pThreads=2, we will get that there
|
||||
are every *two* logical vCPUs sharing a L1/L2 cache, which is not
|
||||
consistent with the vCPU topology (vThreads=1).
|
||||
|
||||
So let's reinitialize BITs[25:14] of Intel CPUID 4 based on the
|
||||
actual vCPU topology instead of host pCPU topology.
|
||||
|
||||
Signed-off-by: Jian Wang <wangjian161@huawei.com>
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
---
|
||||
target/i386/cpu.c | 27 +++++++++++++++++++++++----
|
||||
1 file changed, 23 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index 868cf3e7e8..c1fe2895fd 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -5196,7 +5196,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
{
|
||||
X86CPU *cpu = env_archcpu(env);
|
||||
CPUState *cs = env_cpu(env);
|
||||
- uint32_t die_offset;
|
||||
+ uint32_t die_offset, smt_width;
|
||||
uint32_t limit;
|
||||
uint32_t signature[3];
|
||||
X86CPUTopoInfo topo_info;
|
||||
@@ -5205,6 +5205,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
topo_info.cores_per_die = cs->nr_cores;
|
||||
topo_info.threads_per_core = cs->nr_threads;
|
||||
|
||||
+ die_offset = apicid_die_offset(&topo_info);
|
||||
+ smt_width = apicid_smt_width(&topo_info);
|
||||
+
|
||||
/* Calculate & apply limits for different index ranges */
|
||||
if (index >= 0xC0000000) {
|
||||
limit = env->cpuid_xlevel2;
|
||||
@@ -5272,8 +5275,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
/* cache info: needed for Core compatibility */
|
||||
if (cpu->cache_info_passthrough) {
|
||||
host_cpuid(index, count, eax, ebx, ecx, edx);
|
||||
- /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
|
||||
- *eax &= ~0xFC000000;
|
||||
+ /*
|
||||
+ * QEMU gives out its own APIC IDs, never pass down bits 31..26.
|
||||
+ * Update the cache topo bits 25..14, according to the guest
|
||||
+ * vCPU topology instead of the host pCPU topology.
|
||||
+ */
|
||||
+ *eax &= ~0xFFFFC000;
|
||||
+ switch (count) {
|
||||
+ case 0: /* L1 dcache info */
|
||||
+ case 1: /* L1 icache info */
|
||||
+ case 2: /* L2 cache info */
|
||||
+ *eax |= ((1 << smt_width) - 1) << 14;
|
||||
+ break;
|
||||
+ case 3: /* L3 cache info */
|
||||
+ *eax |= ((1 << die_offset) - 1) << 14;
|
||||
+ break;
|
||||
+ default: /* end of info */
|
||||
+ *eax = *ebx = *ecx = *edx = 0;
|
||||
+ break;
|
||||
+ }
|
||||
if ((*eax & 31) && cs->nr_cores > 1) {
|
||||
*eax |= (cs->nr_cores - 1) << 26;
|
||||
}
|
||||
@@ -5298,7 +5318,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
eax, ebx, ecx, edx);
|
||||
break;
|
||||
case 3: /* L3 cache info */
|
||||
- die_offset = apicid_die_offset(&topo_info);
|
||||
if (cpu->enable_l3_cache) {
|
||||
encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
|
||||
(1 << die_offset), cs->nr_cores,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
45
nbd-server.c-fix-invalid-read-after-client-was-alrea.patch
Normal file
45
nbd-server.c-fix-invalid-read-after-client-was-alrea.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 4b156248776f734d63fe37629d56c40234fda9c0 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 10:42:33 +0800
|
||||
Subject: [PATCH] nbd/server.c: fix invalid read after client was already free
|
||||
|
||||
In the process of NBD equipment pressurization, executing QEMU NBD will
|
||||
lead to the failure of IO distribution and go to NBD_ Out process of trip().
|
||||
If two or more IO go to the out process, client NBD will release in nbd_request_put().
|
||||
The user after free problem that is read again in close().
|
||||
Through the NBD_ Save the value of client > closing before the out process in trip
|
||||
to solve the use after free problem.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
nbd/server.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 4630dd7322..37515ed520 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -2606,6 +2606,7 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
NBDRequestData *req;
|
||||
NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */
|
||||
int ret;
|
||||
+ bool client_closing;
|
||||
Error *local_err = NULL;
|
||||
|
||||
trace_nbd_trip();
|
||||
@@ -2681,8 +2682,11 @@ disconnect:
|
||||
if (local_err) {
|
||||
error_reportf_err(local_err, "Disconnect client, due to: ");
|
||||
}
|
||||
+ client_closing = client->closing;
|
||||
nbd_request_put(req);
|
||||
- client_close(client, true);
|
||||
+ if (!client_closing) {
|
||||
+ client_close(client, true);
|
||||
+ }
|
||||
nbd_client_put(client);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
35
qemu-nbd-make-native-as-the-default-aio-mode.patch
Normal file
35
qemu-nbd-make-native-as-the-default-aio-mode.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From de6f3fb0cf92e04c0989a9065910158eecbe4304 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 10:48:58 +0800
|
||||
Subject: [PATCH] qemu-nbd: make native as the default aio mode
|
||||
|
||||
When the file system is dealing with multithreading concurrent writing to a file,
|
||||
the performance will be degraded because of the lock.
|
||||
At present, the default AIO mode of QEMU NBD is threads. In the case of large blocks,
|
||||
because IO is divided into small pieces and multiple queues, it will become multithreading
|
||||
concurrent writing the same file. Due to the file system, the performance will be greatly reduced.
|
||||
If you change to native mode, this problem will not exist.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
qemu-nbd.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/qemu-nbd.c b/qemu-nbd.c
|
||||
index c6c20df68a..15a4bc4018 100644
|
||||
--- a/qemu-nbd.c
|
||||
+++ b/qemu-nbd.c
|
||||
@@ -800,6 +800,10 @@ int main(int argc, char **argv)
|
||||
trace_init_file();
|
||||
qemu_set_log(LOG_TRACE);
|
||||
|
||||
+ if (!seen_aio && (flags & BDRV_O_NOCACHE)) {
|
||||
+ flags |= BDRV_O_NATIVE_AIO;
|
||||
+ }
|
||||
+
|
||||
socket_activation = check_socket_activation();
|
||||
if (socket_activation == 0) {
|
||||
setup_address_and_port(&bindto, &port);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
42
qemu-nbd-set-timeout-to-qemu-nbd-socket.patch
Normal file
42
qemu-nbd-set-timeout-to-qemu-nbd-socket.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From f665f7836a019cc8bb8d46d076508afc761923f0 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 10:55:08 +0800
|
||||
Subject: [PATCH] qemu-nbd: set timeout to qemu-nbd socket
|
||||
|
||||
In case of insufficient memory and kill-9,
|
||||
the NBD socket cannot be processed and stuck all the time.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
nbd/client.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/nbd/client.c b/nbd/client.c
|
||||
index 30d5383cb1..8ed50140f2 100644
|
||||
--- a/nbd/client.c
|
||||
+++ b/nbd/client.c
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "nbd-internal.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
+#define NBD_TIMEOUT_SECONDS 30
|
||||
+
|
||||
/* Definitions for opaque data types */
|
||||
|
||||
static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
|
||||
@@ -1301,6 +1303,12 @@ int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (ioctl(fd, NBD_SET_TIMEOUT, NBD_TIMEOUT_SECONDS) < 0) {
|
||||
+ int serrno = errno;
|
||||
+ error_setg(errp, "Failed setting timeout");
|
||||
+ return -serrno;
|
||||
+ }
|
||||
+
|
||||
trace_nbd_init_finish();
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
36
qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch
Normal file
36
qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 56f59125707c0222bbb5d7f820792aba17c3db08 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 11:10:42 +0800
|
||||
Subject: [PATCH] qemu-pr: fixed ioctl failed for multipath disk
|
||||
|
||||
We use ioctl to detect multipath devices. However, we only set flags in
|
||||
struct dm_ioctl (the argument to ioctl) and left other fields in random,
|
||||
which may cause the failure of calling ioctl. Hence, we set other
|
||||
fields to 0 to avoid the failure.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
scsi/qemu-pr-helper.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
|
||||
index f281daeced..bbb9b57741 100644
|
||||
--- a/scsi/qemu-pr-helper.c
|
||||
+++ b/scsi/qemu-pr-helper.c
|
||||
@@ -288,9 +288,12 @@ static void multipath_pr_init(void)
|
||||
|
||||
static int is_mpath(int fd)
|
||||
{
|
||||
- struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG };
|
||||
+ struct dm_ioctl dm;
|
||||
struct dm_target_spec *tgt;
|
||||
|
||||
+ memset(&dm, 0, sizeof(struct dm_ioctl));
|
||||
+ dm.flags = DM_NOFLUSH_FLAG;
|
||||
+
|
||||
tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm);
|
||||
if (!tgt) {
|
||||
if (errno == ENXIO) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
76
qemu.spec
76
qemu.spec
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 6.2.0
|
||||
Release: 8
|
||||
Release: 9
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||
@ -47,6 +47,37 @@ Patch0034: Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch
|
||||
Patch0035: cpu-features-fix-bug-for-memory-leakage.patch
|
||||
Patch0036: monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch
|
||||
Patch0037: oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch
|
||||
Patch0038: nbd-server.c-fix-invalid-read-after-client-was-alrea.patch
|
||||
Patch0039: qemu-nbd-make-native-as-the-default-aio-mode.patch
|
||||
Patch0040: qemu-nbd-set-timeout-to-qemu-nbd-socket.patch
|
||||
Patch0041: qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch
|
||||
Patch0042: block-enable-cache-mode-of-empty-cdrom.patch
|
||||
Patch0043: block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch
|
||||
Patch0044: scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch
|
||||
Patch0045: block-bugfix-disable-process-AIO-when-attach-scsi-di.patch
|
||||
Patch0046: block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch
|
||||
Patch0047: scsi-bugfix-fix-division-by-zero.patch
|
||||
Patch0048: i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch
|
||||
Patch0049: i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch
|
||||
Patch0050: target-arm-convert-isar-regs-to-array.patch
|
||||
Patch0051: target-arm-parse-cpu-feature-related-options.patch
|
||||
Patch0052: target-arm-register-CPU-features-for-property.patch
|
||||
Patch0053: target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
|
||||
Patch0054: target-arm-introduce-CPU-feature-dependency-mechanis.patch
|
||||
Patch0055: target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
|
||||
Patch0056: target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
|
||||
Patch0057: target-arm-Add-more-CPU-features.patch
|
||||
Patch0058: target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch
|
||||
Patch0059: target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch
|
||||
Patch0060: target-arm-Fix-write-redundant-values-to-kvm.patch
|
||||
Patch0061: target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch
|
||||
Patch0062: target-arm-Update-the-ID-registers-of-Kunpeng-920.patch
|
||||
Patch0063: freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch
|
||||
Patch0064: freeclock-set-rtc_date_diff-for-arm.patch
|
||||
Patch0065: freeclock-set-rtc_date_diff-for-X86.patch
|
||||
Patch0066: hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch
|
||||
Patch0067: hw-net-rocker-fix-security-vulnerability.patch
|
||||
Patch0068: tests-Disable-filemonitor-testcase.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: gcc
|
||||
@ -491,6 +522,49 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- hw/net/rocker: fix security vulnerability
|
||||
- tests: Disable filemonitor testcase
|
||||
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- hw/usb: reduce the vpcu cost of UHCI when VNC disconnect
|
||||
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- freeclock: add qmp command to get time offset of vm in seconds
|
||||
- freeclock: set rtc_date_diff for arm
|
||||
- freeclock: set rtc_date_diff for X86
|
||||
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- target/arm: convert isar regs to array
|
||||
- target/arm: parse cpu feature related options
|
||||
- target/arm: register CPU features for property
|
||||
- target/arm: Allow ID registers to synchronize to KVM
|
||||
- target/arm: introduce CPU feature dependency mechanism
|
||||
- target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
|
||||
- target/arm: Add CPU features to query-cpu-model-expansion
|
||||
- target/arm: Add more CPU features
|
||||
- target/arm: ignore evtstrm and cpuid CPU features
|
||||
- target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest
|
||||
- target/arm: Fix write redundant values to kvm
|
||||
- target/arm: clear EL2 and EL3 only when kvm is not enabled
|
||||
- target/arm: Update the ID registers of Kunpeng-920
|
||||
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based on vCPU topo
|
||||
- i386: cache passthrough: Update AMD 8000_001D.EAX[25:14] based on vCPU topo
|
||||
|
||||
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
|
||||
- nbd/server.c: fix invalid read after client was already free
|
||||
- qemu-nbd: make native as the default aio mode
|
||||
- qemu-nbd: set timeout to qemu-nbd socket
|
||||
- qemu-pr: fixed ioctl failed for multipath disk
|
||||
- block: enable cache mode of empty cdrom
|
||||
- block: disallow block jobs when there is a BDRV_O_INACTIVE flag
|
||||
- scsi: cdrom: Fix crash after remote cdrom detached
|
||||
- block: bugfix: disable process AIO when attach scsi disk
|
||||
- block: bugfix: Don't pause vm when NOSPACE EIO happened
|
||||
- scsi: bugfix: fix division by zero
|
||||
|
||||
* Fri Feb 11 2022 imxcc <xingchaochao@huawei.com>
|
||||
- migration: skip cache_drop for bios bootloader and
|
||||
- ps2: fix oob in ps2 kbd
|
||||
|
||||
57
scsi-bugfix-fix-division-by-zero.patch
Normal file
57
scsi-bugfix-fix-division-by-zero.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From ba8fd8a3d11655da0b51148e69c01b78794a3f69 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 16:34:05 +0800
|
||||
Subject: [PATCH] scsi: bugfix: fix division by zero
|
||||
|
||||
Error of PRDM disk may cause divide by zero in
|
||||
scsi_read_complete(), so add LOG and assert().
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
hw/scsi/scsi-generic.c | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
|
||||
index 0306ccc7b1..1f51586048 100644
|
||||
--- a/hw/scsi/scsi-generic.c
|
||||
+++ b/hw/scsi/scsi-generic.c
|
||||
@@ -179,6 +179,10 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
|
||||
(r->req.cmd.buf[1] & 0x01)) {
|
||||
page = r->req.cmd.buf[2];
|
||||
if (page == 0xb0) {
|
||||
+ if (s->blocksize == 0) {
|
||||
+ qemu_log("device blocksize is 0!\n");
|
||||
+ abort();
|
||||
+ }
|
||||
uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
|
||||
uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
|
||||
|
||||
@@ -314,11 +318,23 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||
/* Snoop READ CAPACITY output to set the blocksize. */
|
||||
if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
|
||||
(ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
|
||||
- s->blocksize = ldl_be_p(&r->buf[4]);
|
||||
+ int new_blocksize = ldl_be_p(&r->buf[4]);
|
||||
+ if (s->blocksize != new_blocksize) {
|
||||
+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n",
|
||||
+ s->qdev.id ? s->qdev.id : "null", s->type,
|
||||
+ s->blocksize, new_blocksize);
|
||||
+ }
|
||||
+ s->blocksize = new_blocksize;
|
||||
s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
|
||||
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
|
||||
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
|
||||
- s->blocksize = ldl_be_p(&r->buf[8]);
|
||||
+ int new_blocksize = ldl_be_p(&r->buf[8]);
|
||||
+ if (s->blocksize != new_blocksize) {
|
||||
+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n",
|
||||
+ s->qdev.id ? s->qdev.id : "null", s->type,
|
||||
+ s->blocksize, new_blocksize);
|
||||
+ }
|
||||
+ s->blocksize = new_blocksize;
|
||||
s->max_lba = ldq_be_p(&r->buf[0]);
|
||||
}
|
||||
blk_set_guest_block_size(s->conf.blk, s->blocksize);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
35
scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch
Normal file
35
scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 77496578b22e127eb50a5a8c463e92fb3245a7e0 Mon Sep 17 00:00:00 2001
|
||||
From: WangJian <wangjian161@huawei.com>
|
||||
Date: Wed, 9 Feb 2022 11:42:47 +0800
|
||||
Subject: [PATCH] scsi: cdrom: Fix crash after remote cdrom detached
|
||||
|
||||
There is a small window between the twice blk_is_available in
|
||||
scsi_disk_emulate_command which would cause crash due to the later
|
||||
assertion if the remote cdrom is detached in this window.
|
||||
|
||||
So this patch replaces assertions with return to avoid qemu crash.
|
||||
|
||||
Signed-off-by: wangjian161 <wangjian161@huawei.com>
|
||||
---
|
||||
hw/scsi/scsi-disk.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||||
index d4914178ea..a1053f4036 100644
|
||||
--- a/hw/scsi/scsi-disk.c
|
||||
+++ b/hw/scsi/scsi-disk.c
|
||||
@@ -1930,7 +1930,10 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
|
||||
memset(outbuf, 0, r->buflen);
|
||||
switch (req->cmd.buf[0]) {
|
||||
case TEST_UNIT_READY:
|
||||
- assert(blk_is_available(s->qdev.conf.blk));
|
||||
+ if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
+ scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||
+ return 0;
|
||||
+ }
|
||||
break;
|
||||
case INQUIRY:
|
||||
buflen = scsi_disk_emulate_inquiry(req, outbuf);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
90
target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
Normal file
90
target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From e6dd7faeea77206d7e6589cbb54ad43926457052 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:58 +0800
|
||||
Subject: [PATCH] target/arm: Add CPU features to query-cpu-model-expansion
|
||||
|
||||
Add CPU features to the result of query-cpu-model-expansion so that
|
||||
other applications (such as libvirt) can know the supported CPU
|
||||
features.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 27 +++++++++++++++++++++++++++
|
||||
target/arm/cpu.h | 2 ++
|
||||
target/arm/monitor.c | 2 ++
|
||||
3 files changed, 31 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index 3024f4a3f5..2d6a26336f 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
+#include "qapi/qmp/qdict.h"
|
||||
+#include "qom/qom-qobject.h"
|
||||
#include "cpu.h"
|
||||
#ifdef CONFIG_TCG
|
||||
#include "hw/core/tcg-cpu-ops.h"
|
||||
@@ -1580,6 +1582,31 @@ static const CPUFeatureDep feature_dependencies[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features)
|
||||
+{
|
||||
+ Object *obj = OBJECT(cpu);
|
||||
+ const char *name;
|
||||
+ ObjectProperty *prop;
|
||||
+ bool is_32bit = !arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(cpu_features); ++i) {
|
||||
+ if (is_32bit != cpu_features[i].is_32bit) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ name = cpu_features[i].name;
|
||||
+ prop = object_property_find(obj, name);
|
||||
+ if (prop) {
|
||||
+ QObject *value;
|
||||
+
|
||||
+ assert(prop->get);
|
||||
+ value = object_property_get_qobject(obj, name, &error_abort);
|
||||
+ qdict_put_obj(features, name, value);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||
index 3dda33f347..947897d5ac 100644
|
||||
--- a/target/arm/cpu.h
|
||||
+++ b/target/arm/cpu.h
|
||||
@@ -4398,4 +4398,6 @@ static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
|
||||
#define cpu_isar_feature(name, cpu) \
|
||||
({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
|
||||
|
||||
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features);
|
||||
+
|
||||
#endif
|
||||
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
|
||||
index 80c64fa355..4c6f1181d9 100644
|
||||
--- a/target/arm/monitor.c
|
||||
+++ b/target/arm/monitor.c
|
||||
@@ -217,6 +217,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
}
|
||||
}
|
||||
|
||||
+ arm_cpu_features_to_dict(ARM_CPU(obj), qdict_out);
|
||||
+
|
||||
if (!qdict_size(qdict_out)) {
|
||||
qobject_unref(qdict_out);
|
||||
} else {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
31
target-arm-Add-more-CPU-features.patch
Normal file
31
target-arm-Add-more-CPU-features.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 85d5b46d8225c5875b8b3ff68967d46bcde9a549 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Tue, 11 Aug 2020 10:28:10 +0800
|
||||
Subject: [PATCH] target/arm: Add more CPU features
|
||||
|
||||
Add i8mm, bf16, and dgh CPU features for AArch64.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index 2d6a26336f..1c1647a0a8 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -1309,6 +1309,9 @@ static struct CPUFeatureInfo cpu_features[] = {
|
||||
FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
|
||||
FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
|
||||
FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
|
||||
+ FIELD_INFO("i8mm", ID_AA64ISAR1, I8MM, false, 1, 0, false),
|
||||
+ FIELD_INFO("bf16", ID_AA64ISAR1, BF16, false, 1, 0, false),
|
||||
+ FIELD_INFO("dgh", ID_AA64ISAR1, DGH, false, 1, 0, false),
|
||||
|
||||
FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
|
||||
FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
|
||||
--
|
||||
2.27.0
|
||||
|
||||
161
target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
Normal file
161
target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From 0272c52e36ab95389e665ca19b129178b0b46eac Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:40 +0800
|
||||
Subject: [PATCH] target/arm: Allow ID registers to synchronize to KVM
|
||||
|
||||
There are 2 steps to synchronize the values of system registers from
|
||||
CPU state to KVM:
|
||||
1. write to the values of system registers from CPU state to
|
||||
(index,value) list by write_cpustate_to_list;
|
||||
2. write the values in (index,value) list to KVM by
|
||||
write_list_to_kvmstate;
|
||||
|
||||
In step 1, the values of constant system registers are not allowed to
|
||||
write to (index,value) list. However, a constant system register is
|
||||
CONSTANT for guest but not for QEMU, which means, QEMU can set/modify
|
||||
the value of constant system registers that is different from phsical
|
||||
registers when startup. But if KVM is enabled, guest can not read the
|
||||
values of the system registers which QEMU set unless they can be written
|
||||
to (index,value) list. And why not try to write to KVM if kvm_sync is
|
||||
true?
|
||||
|
||||
At the moment we call write_cpustate_to_list, all ID registers are
|
||||
contant, including ID_PFR1_EL1 and ID_AA64PFR0_EL1 because GIC has been
|
||||
initialized. Hence, let's give all ID registers a chance to write to
|
||||
KVM. If the write is successful, then write to (index,value) list.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/helper.c | 31 ++++++++++++++++++++-----------
|
||||
target/arm/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
target/arm/kvm_arm.h | 3 +++
|
||||
3 files changed, 61 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||
index b8ea1dc1f6..79f77705c3 100644
|
||||
--- a/target/arm/helper.c
|
||||
+++ b/target/arm/helper.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "exec/cpu_ldst.h"
|
||||
#include "semihosting/common-semi.h"
|
||||
#endif
|
||||
+#include "kvm_arm.h"
|
||||
|
||||
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
|
||||
#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
|
||||
@@ -149,30 +150,38 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
- if (ri->type & ARM_CP_NO_RAW) {
|
||||
+ /*
|
||||
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||
+ * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
|
||||
+ * synchronize to kvm.
|
||||
+ */
|
||||
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
|
||||
+ ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
newval = read_raw_cp_reg(&cpu->env, ri);
|
||||
if (kvm_sync) {
|
||||
- /*
|
||||
- * Only sync if the previous list->cpustate sync succeeded.
|
||||
- * Rather than tracking the success/failure state for every
|
||||
- * item in the list, we just recheck "does the raw write we must
|
||||
- * have made in write_list_to_cpustate() read back OK" here.
|
||||
- */
|
||||
- uint64_t oldval = cpu->cpreg_values[i];
|
||||
+ /* Only sync if we can sync to KVM successfully. */
|
||||
+ uint64_t oldval;
|
||||
+ uint64_t kvmval;
|
||||
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
if (oldval == newval) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- write_raw_cp_reg(&cpu->env, ri, oldval);
|
||||
- if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
|
||||
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||
+ kvmval != newval) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- write_raw_cp_reg(&cpu->env, ri, newval);
|
||||
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||
}
|
||||
cpu->cpreg_values[i] = newval;
|
||||
}
|
||||
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
|
||||
index bbf1ce7ba3..59d556724f 100644
|
||||
--- a/target/arm/kvm.c
|
||||
+++ b/target/arm/kvm.c
|
||||
@@ -514,6 +514,44 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target)
|
||||
+{
|
||||
+ uint32_t v32;
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (regidx & KVM_REG_SIZE_MASK) {
|
||||
+ case KVM_REG_SIZE_U32:
|
||||
+ ret = kvm_get_one_reg(CPU(cpu), regidx, &v32);
|
||||
+ if (ret == 0) {
|
||||
+ *target = v32;
|
||||
+ }
|
||||
+ return ret;
|
||||
+ case KVM_REG_SIZE_U64:
|
||||
+ return kvm_get_one_reg(CPU(cpu), regidx, target);
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source)
|
||||
+{
|
||||
+ uint32_t v32;
|
||||
+
|
||||
+ switch (regidx & KVM_REG_SIZE_MASK) {
|
||||
+ case KVM_REG_SIZE_U32:
|
||||
+ v32 = *source;
|
||||
+ if (v32 != *source) {
|
||||
+ error_report("the value of source is too large");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return kvm_set_one_reg(CPU(cpu), regidx, &v32);
|
||||
+ case KVM_REG_SIZE_U64:
|
||||
+ return kvm_set_one_reg(CPU(cpu), regidx, source);
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
bool write_kvmstate_to_list(ARMCPU *cpu)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
|
||||
index b7f78b5215..f8e0e64363 100644
|
||||
--- a/target/arm/kvm_arm.h
|
||||
+++ b/target/arm/kvm_arm.h
|
||||
@@ -528,4 +528,7 @@ static inline const char *its_class_name(void)
|
||||
}
|
||||
}
|
||||
|
||||
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target);
|
||||
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source);
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.27.0
|
||||
|
||||
119
target-arm-Fix-write-redundant-values-to-kvm.patch
Normal file
119
target-arm-Fix-write-redundant-values-to-kvm.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From 9680adfba5ca871f69a6fbd15b92571fc2a52d78 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Wed, 9 Dec 2020 19:35:08 +0800
|
||||
Subject: [PATCH] target/arm: Fix write redundant values to kvm
|
||||
|
||||
After modifying the value of a ID register, we'd better to try to write
|
||||
it to KVM so that we can known the value is acceptable for KVM.
|
||||
Because it may modify the registers' values of KVM, it's not suitable
|
||||
for other registers.
|
||||
|
||||
(cherry-picked from a0d7a9de807639fcfcbe1fe037cb8772d459a9cf)
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/helper.c | 73 ++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 49 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||
index 4c7b4cadfa..1dd5d64d96 100644
|
||||
--- a/target/arm/helper.c
|
||||
+++ b/target/arm/helper.c
|
||||
@@ -134,6 +134,16 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool is_id_reg(const ARMCPRegInfo *ri)
|
||||
+{
|
||||
+ /*
|
||||
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||
+ * where 1<=crm<8, 0<=op2<8.
|
||||
+ */
|
||||
+ return ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 &&
|
||||
+ ri->crm > 0 && ri->crm < 8;
|
||||
+}
|
||||
+
|
||||
bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||
{
|
||||
/* Write the coprocessor state from cpu->env to the (index,value) list. */
|
||||
@@ -150,38 +160,53 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
- /*
|
||||
- * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||
- * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
|
||||
- * synchronize to kvm.
|
||||
- */
|
||||
- if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
|
||||
- ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
|
||||
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && is_id_reg(ri))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
newval = read_raw_cp_reg(&cpu->env, ri);
|
||||
if (kvm_sync) {
|
||||
- /* Only sync if we can sync to KVM successfully. */
|
||||
- uint64_t oldval;
|
||||
- uint64_t kvmval;
|
||||
+ if (is_id_reg(ri)) {
|
||||
+ /* Only sync if we can sync to KVM successfully. */
|
||||
+ uint64_t oldval;
|
||||
+ uint64_t kvmval;
|
||||
|
||||
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||
- continue;
|
||||
- }
|
||||
- if (oldval == newval) {
|
||||
- continue;
|
||||
- }
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (oldval == newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||
- continue;
|
||||
- }
|
||||
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||
- kvmval != newval) {
|
||||
- continue;
|
||||
- }
|
||||
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||
+ kvmval != newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Only sync if the previous list->cpustate sync succeeded.
|
||||
+ * Rather than tracking the success/failure state for every
|
||||
+ * item in the list, we just recheck "does the raw write we must
|
||||
+ * have made in write_list_to_cpustate() read back OK" here.
|
||||
+ */
|
||||
+ uint64_t oldval = cpu->cpreg_values[i];
|
||||
+
|
||||
+ if (oldval == newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||
+ write_raw_cp_reg(&cpu->env, ri, oldval);
|
||||
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ write_raw_cp_reg(&cpu->env, ri, newval);
|
||||
+ }
|
||||
}
|
||||
cpu->cpreg_values[i] = newval;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
58
target-arm-Update-the-ID-registers-of-Kunpeng-920.patch
Normal file
58
target-arm-Update-the-ID-registers-of-Kunpeng-920.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From e2cb8b57278357c0a42cf7722b8c28b6f8d7585c Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Sat, 19 Sep 2020 09:04:45 +0800
|
||||
Subject: [PATCH] target/arm: Update the ID registers of Kunpeng-920
|
||||
|
||||
The values of some ID registers in Kunpeng-920 are not exactly correct.
|
||||
Let's update them. The values are read from Kunpeng-920 by calling
|
||||
read_sysreg_s.
|
||||
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu64.c | 27 +++++++++++++++++++++++++--
|
||||
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||
index 287e7ac91c..3ec788fc29 100644
|
||||
--- a/target/arm/cpu64.c
|
||||
+++ b/target/arm/cpu64.c
|
||||
@@ -262,10 +262,33 @@ static void aarch64_kunpeng_920_initfn(Object *obj)
|
||||
|
||||
cpu->midr = 0x480fd010;
|
||||
cpu->ctr = 0x84448004;
|
||||
- cpu->isar.regs[ID_AA64PFR0] = 0x11001111;
|
||||
+ cpu->isar.regs[ID_ISAR0] = 0;
|
||||
+ cpu->isar.regs[ID_ISAR1] = 0;
|
||||
+ cpu->isar.regs[ID_ISAR2] = 0;
|
||||
+ cpu->isar.regs[ID_ISAR3] = 0;
|
||||
+ cpu->isar.regs[ID_ISAR4] = 0;
|
||||
+ cpu->isar.regs[ID_ISAR5] = 0;
|
||||
+ cpu->isar.regs[ID_MMFR0] = 0;
|
||||
+ cpu->isar.regs[ID_MMFR1] = 0;
|
||||
+ cpu->isar.regs[ID_MMFR2] = 0;
|
||||
+ cpu->isar.regs[ID_MMFR3] = 0;
|
||||
+ cpu->isar.regs[ID_MMFR4] = 0;
|
||||
+ cpu->isar.regs[MVFR0] = 0;
|
||||
+ cpu->isar.regs[MVFR1] = 0;
|
||||
+ cpu->isar.regs[MVFR2] = 0;
|
||||
+ cpu->isar.regs[ID_DFR0] = 0;
|
||||
+ cpu->isar.regs[MVFR2] = 0;
|
||||
+ cpu->isar.regs[MVFR2] = 0;
|
||||
+ cpu->isar.regs[MVFR2] = 0;
|
||||
+ cpu->isar.regs[ID_PFR0] = 0;
|
||||
+ cpu->isar.regs[ID_PFR1] = 0;
|
||||
+ cpu->isar.regs[ID_AA64PFR0] = 0x0000010011111111;
|
||||
cpu->isar.regs[ID_AA64DFR0] = 0x110305408;
|
||||
- cpu->isar.regs[ID_AA64ISAR0] = 0x10211120;
|
||||
+ cpu->isar.regs[ID_AA64ISAR0] = 0x0001100010211120;
|
||||
+ cpu->isar.regs[ID_AA64ISAR1] = 0x00011001;
|
||||
cpu->isar.regs[ID_AA64MMFR0] = 0x101125;
|
||||
+ cpu->isar.regs[ID_AA64MMFR1] = 0x10211122;
|
||||
+ cpu->isar.regs[ID_AA64MMFR2] = 0x00001011;
|
||||
}
|
||||
|
||||
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
43
target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch
Normal file
43
target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 20bd52038a960e0c959af38a5d3d7a6601db8e8b Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Mon, 21 Sep 2020 22:14:20 +0800
|
||||
Subject: [PATCH] target/arm: clear EL2 and EL3 only when kvm is not enabled
|
||||
|
||||
When has_el2 and has_el3 are disabled, which is the default value for
|
||||
virt machine, QEMU will clear the corresponding field in ID_PFR1_EL1 and
|
||||
ID_AA64PFR0_EL1 to not expose EL3 and EL2 to guest. Because KVM doesn't
|
||||
support to emulate ID registers in AArch64 before, it will not take
|
||||
effect. Hence, clear EL2 and EL3 only when kvm is not enabled for
|
||||
backwards compatibility.
|
||||
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index 1c1647a0a8..65163f5135 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -2283,7 +2283,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
- if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
|
||||
+ if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3 && !kvm_enabled()) {
|
||||
/* If the has_el3 CPU property is disabled then we need to disable the
|
||||
* feature.
|
||||
*/
|
||||
@@ -2324,7 +2324,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
cpu->pmceid1 = 0;
|
||||
}
|
||||
|
||||
- if (!arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
+ if (!arm_feature(env, ARM_FEATURE_EL2) && !kvm_enabled()) {
|
||||
/* Disable the hypervisor feature bits in the processor feature
|
||||
* registers if we don't have EL2. These are id_pfr1[15:12] and
|
||||
* id_aa64pfr0_el1[11:8].
|
||||
--
|
||||
2.27.0
|
||||
|
||||
2781
target-arm-convert-isar-regs-to-array.patch
Normal file
2781
target-arm-convert-isar-regs-to-array.patch
Normal file
File diff suppressed because it is too large
Load Diff
67
target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch
Normal file
67
target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 4558dc5590b89b1252baea2734c2b3668566e5cb Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Mon, 7 Sep 2020 14:07:07 +0800
|
||||
Subject: [PATCH] target/arm: ignore evtstrm and cpuid CPU features
|
||||
|
||||
evtstrm and cpuid cann't be controlled by VMM:
|
||||
1. evtstrm: The generic timer is configured to generate events at a
|
||||
frequency of approximately 100KHz. It's controlled by the linux
|
||||
kernel config CONFIG_ARM_ARCH_TIMER_EVTSTREAM.
|
||||
2. cpuid: EL0 access to certain ID registers is available. It's always
|
||||
set by linux kernel after 77c97b4ee2129 ("arm64: cpufeature: Expose
|
||||
CPUID registers by emulation").
|
||||
However, they are exposed by getauxval() and /proc/cpuinfo. Hence,
|
||||
let's report and ignore the CPU features if someone set them.
|
||||
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu64.c | 29 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||
index 9e5179afbe..287e7ac91c 100644
|
||||
--- a/target/arm/cpu64.c
|
||||
+++ b/target/arm/cpu64.c
|
||||
@@ -982,10 +982,37 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs)
|
||||
return g_strdup("aarch64");
|
||||
}
|
||||
|
||||
+static const char *unconfigurable_feats[] = {
|
||||
+ "evtstrm",
|
||||
+ "cpuid",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static bool is_configurable_feat(const char *name)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; unconfigurable_feats[i]; ++i) {
|
||||
+ if (g_strcmp0(unconfigurable_feats[i], name) == 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
|
||||
{
|
||||
- GlobalProperty *prop = g_new0(typeof(*prop), 1);
|
||||
+ GlobalProperty *prop;
|
||||
+
|
||||
+ if (!is_configurable_feat(name)) {
|
||||
+ info_report("CPU feature '%s' is not configurable by QEMU. Ignore it.",
|
||||
+ name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ prop = g_new0(typeof(*prop), 1);
|
||||
prop->driver = typename;
|
||||
prop->property = g_strdup(name);
|
||||
prop->value = g_strdup(val);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
185
target-arm-introduce-CPU-feature-dependency-mechanis.patch
Normal file
185
target-arm-introduce-CPU-feature-dependency-mechanis.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From 632d58d1b908ee979074b589417f446c0a3be35d Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:46 +0800
|
||||
Subject: [PATCH] target/arm: introduce CPU feature dependency mechanism
|
||||
|
||||
Some CPU features are dependent on other CPU features. For example,
|
||||
ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same
|
||||
value, which means FP and ADVSIMD are dependent on each other, FPHP and
|
||||
ADVSIMDHP are dependent on each other.
|
||||
|
||||
This commit introduces a mechanism for CPU feature dependency in
|
||||
AArch64. We build a directed graph from the CPU feature dependency
|
||||
relationship, each edge from->to means the `to` CPU feature is dependent
|
||||
on the `from` CPU feature. And we will automatically enable/disable CPU
|
||||
feature according to the directed graph.
|
||||
|
||||
For example, a, b, and c CPU features are in relationship a->b->c, which
|
||||
means c is dependent on b and b is dependent on a. If c is enabled by
|
||||
user, then a and b is enabled automatically. And if a is disabled by
|
||||
user, then b and c is disabled automatically.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 129 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index c081ecc12b..ee09642dae 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -1483,6 +1483,103 @@ static struct CPUFeatureInfo cpu_features[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+typedef struct CPUFeatureDep {
|
||||
+ CPUFeatureInfo from, to;
|
||||
+} CPUFeatureDep;
|
||||
+
|
||||
+static const CPUFeatureDep feature_dependencies[] = {
|
||||
+ {
|
||||
+ .from = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||
+ .to = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||
+ .to = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||
+ },
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .from = {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||
+ },
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+
|
||||
+ .from = FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+
|
||||
+ .from = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||
+ .to = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||
+ .to = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||
+ .to = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||
+ },
|
||||
+ {
|
||||
+ .from = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||
+ .to = {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .from = {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||
+ },
|
||||
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
@@ -1519,13 +1616,45 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
}
|
||||
|
||||
if (value) {
|
||||
+ if (object_property_get_bool(obj, feat->name, NULL)) {
|
||||
+ return;
|
||||
+ }
|
||||
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||
feat->shift, feat->length,
|
||||
feat->min_value);
|
||||
+ /* Auto enable the features which current feature is dependent on. */
|
||||
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
|
||||
+ const CPUFeatureDep *d = &feature_dependencies[i];
|
||||
+ if (strcmp(d->to.name, feat->name) != 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ object_property_set_bool(obj, d->from.name, true, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
} else {
|
||||
+ if (!object_property_get_bool(obj, feat->name, NULL)) {
|
||||
+ return;
|
||||
+ }
|
||||
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||
feat->shift, feat->length,
|
||||
feat->ni_value);
|
||||
+ /* Auto disable the features which are dependent on current feature. */
|
||||
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
|
||||
+ const CPUFeatureDep *d = &feature_dependencies[i];
|
||||
+ if (strcmp(d->from.name, feat->name) != 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ object_property_set_bool(obj, d->to.name, false, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
93
target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
Normal file
93
target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From 536aa9ecc3cb25c81c2df56230c690257189d4ef Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:55 +0800
|
||||
Subject: [PATCH] target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
|
||||
|
||||
Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set
|
||||
CPU features in ARM.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
linux-headers/linux/kvm.h | 2 ++
|
||||
target/arm/cpu.c | 5 +++++
|
||||
target/arm/kvm64.c | 14 ++++++++++++++
|
||||
target/arm/kvm_arm.h | 7 +++++++
|
||||
4 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index bcaf66cc4d..5d8e42b8f8 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -1113,6 +1113,8 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
|
||||
#define KVM_CAP_ARM_MTE 205
|
||||
|
||||
+#define KVM_CAP_ARM_CPU_FEATURE 555
|
||||
+
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
struct kvm_irq_routing_irqchip {
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index ee09642dae..3024f4a3f5 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -1604,6 +1604,11 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
Error *local_err = NULL;
|
||||
bool value;
|
||||
|
||||
+ if (!kvm_arm_cpu_feature_supported()) {
|
||||
+ warn_report("KVM doesn't support to set CPU feature in arm. "
|
||||
+ "Setting to `%s` is ignored.", name);
|
||||
+ return;
|
||||
+ }
|
||||
if (dev->realized) {
|
||||
qdev_prop_set_after_realize(dev, name, errp);
|
||||
return;
|
||||
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
|
||||
index 4f97e516c2..b34a87fd24 100644
|
||||
--- a/target/arm/kvm64.c
|
||||
+++ b/target/arm/kvm64.c
|
||||
@@ -827,6 +827,20 @@ static int kvm_arm_sve_set_vls(CPUState *cs)
|
||||
return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
}
|
||||
|
||||
+bool kvm_arm_cpu_feature_supported(void)
|
||||
+{
|
||||
+ static bool cpu_feature_initialized;
|
||||
+ static bool cpu_feature_supported;
|
||||
+
|
||||
+ if (!cpu_feature_initialized) {
|
||||
+ cpu_feature_supported = kvm_check_extension(kvm_state,
|
||||
+ KVM_CAP_ARM_CPU_FEATURE);
|
||||
+ cpu_feature_initialized = true;
|
||||
+ }
|
||||
+
|
||||
+ return cpu_feature_supported;
|
||||
+}
|
||||
+
|
||||
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
|
||||
index f8e0e64363..82145607ec 100644
|
||||
--- a/target/arm/kvm_arm.h
|
||||
+++ b/target/arm/kvm_arm.h
|
||||
@@ -306,6 +306,13 @@ bool kvm_arm_pmu_supported(void);
|
||||
*/
|
||||
bool kvm_arm_sve_supported(void);
|
||||
|
||||
+/**
|
||||
+ * kvm_arm_cpu_feature_supported:
|
||||
+ *
|
||||
+ * Returns true if KVM can set CPU features and false otherwise.
|
||||
+ */
|
||||
+bool kvm_arm_cpu_feature_supported(void);
|
||||
+
|
||||
/**
|
||||
* kvm_arm_get_max_vm_ipa_size:
|
||||
* @ms: Machine state handle
|
||||
--
|
||||
2.27.0
|
||||
|
||||
32
target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch
Normal file
32
target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 3371917ea92265377f87692a717397267416c4aa Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Wed, 16 Sep 2020 19:40:28 +0800
|
||||
Subject: [PATCH] target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest
|
||||
|
||||
Some AArch64 CPU doesn't support AArch32 mode, and the values of AArch32
|
||||
registers are all 0. Hence, We'd better not to modify AArch32 registers
|
||||
in AArch64 mode.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/helper.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||
index 79f77705c3..4c7b4cadfa 100644
|
||||
--- a/target/arm/helper.c
|
||||
+++ b/target/arm/helper.c
|
||||
@@ -6718,7 +6718,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
ARMCPU *cpu = env_archcpu(env);
|
||||
uint64_t pfr1 = cpu->isar.regs[ID_PFR1];
|
||||
|
||||
- if (env->gicv3state) {
|
||||
+ if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && env->gicv3state) {
|
||||
pfr1 |= 1 << 28;
|
||||
}
|
||||
return pfr1;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
125
target-arm-parse-cpu-feature-related-options.patch
Normal file
125
target-arm-parse-cpu-feature-related-options.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From abd51f8d46b916efb37cb2c8face176bc83c0d5d Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:35 +0800
|
||||
Subject: [PATCH] target/arm: parse cpu feature related options
|
||||
|
||||
The implementation of CPUClass::parse_features only supports CPU
|
||||
features in "feature=value" format. However, libvirt maybe send us a
|
||||
CPU feature string in "+feature/-feature" format. Hence, we need to
|
||||
override CPUClass::parse_features to support CPU feature string in both
|
||||
"feature=value" and "+feature/-feature" format.
|
||||
|
||||
The logic of AArch64CPUClass::parse_features is similar to that of
|
||||
X86CPUClass::parse_features.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu64.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 83 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||
index 96a49a3158..9e5179afbe 100644
|
||||
--- a/target/arm/cpu64.c
|
||||
+++ b/target/arm/cpu64.c
|
||||
@@ -982,6 +982,88 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs)
|
||||
return g_strdup("aarch64");
|
||||
}
|
||||
|
||||
+static void
|
||||
+cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
|
||||
+{
|
||||
+ GlobalProperty *prop = g_new0(typeof(*prop), 1);
|
||||
+ prop->driver = typename;
|
||||
+ prop->property = g_strdup(name);
|
||||
+ prop->value = g_strdup(val);
|
||||
+ qdev_prop_register_global(prop);
|
||||
+}
|
||||
+
|
||||
+static gint compare_string(gconstpointer a, gconstpointer b)
|
||||
+{
|
||||
+ return g_strcmp0(a, b);
|
||||
+}
|
||||
+
|
||||
+static GList *plus_features, *minus_features;
|
||||
+
|
||||
+static void aarch64_cpu_parse_features(const char *typename, char *features,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ GList *l;
|
||||
+ char *featurestr; /* Single 'key=value" string being parsed */
|
||||
+ static bool cpu_globals_initialized;
|
||||
+
|
||||
+ if (cpu_globals_initialized) {
|
||||
+ return;
|
||||
+ }
|
||||
+ cpu_globals_initialized = true;
|
||||
+
|
||||
+ if (!features) {
|
||||
+ return;
|
||||
+ }
|
||||
+ for (featurestr = strtok(features, ",");
|
||||
+ featurestr;
|
||||
+ featurestr = strtok(NULL, ",")) {
|
||||
+ const char *name;
|
||||
+ const char *val = NULL;
|
||||
+ char *eq = NULL;
|
||||
+
|
||||
+ /* Compatibility syntax: */
|
||||
+ if (featurestr[0] == '+') {
|
||||
+ plus_features = g_list_append(plus_features,
|
||||
+ g_strdup(featurestr + 1));
|
||||
+ continue;
|
||||
+ } else if (featurestr[0] == '-') {
|
||||
+ minus_features = g_list_append(minus_features,
|
||||
+ g_strdup(featurestr + 1));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ eq = strchr(featurestr, '=');
|
||||
+ name = featurestr;
|
||||
+ if (eq) {
|
||||
+ *eq++ = 0;
|
||||
+ val = eq;
|
||||
+ } else {
|
||||
+ error_setg(errp, "Unsupported property format: %s", name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (g_list_find_custom(plus_features, name, compare_string)) {
|
||||
+ warn_report("Ambiguous CPU model string. "
|
||||
+ "Don't mix both \"+%s\" and \"%s=%s\"",
|
||||
+ name, name, val);
|
||||
+ }
|
||||
+ if (g_list_find_custom(minus_features, name, compare_string)) {
|
||||
+ warn_report("Ambiguous CPU model string. "
|
||||
+ "Don't mix both \"-%s\" and \"%s=%s\"",
|
||||
+ name, name, val);
|
||||
+ }
|
||||
+ cpu_add_feat_as_prop(typename, name, val);
|
||||
+ }
|
||||
+
|
||||
+ for (l = plus_features; l; l = l->next) {
|
||||
+ cpu_add_feat_as_prop(typename, l->data, "on");
|
||||
+ }
|
||||
+
|
||||
+ for (l = minus_features; l; l = l->next) {
|
||||
+ cpu_add_feat_as_prop(typename, l->data, "off");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
@@ -991,6 +1073,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||
cc->gdb_num_core_regs = 34;
|
||||
cc->gdb_core_xml_file = "aarch64-core.xml";
|
||||
cc->gdb_arch_name = aarch64_gdb_arch_name;
|
||||
+ cc->parse_features = aarch64_cpu_parse_features;
|
||||
|
||||
object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
|
||||
aarch64_cpu_set_aarch64);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
399
target-arm-register-CPU-features-for-property.patch
Normal file
399
target-arm-register-CPU-features-for-property.patch
Normal file
@ -0,0 +1,399 @@
|
||||
From 9fd09aabba558b39ca949ef376d05bc0779fdda6 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Thu, 6 Aug 2020 16:14:37 +0800
|
||||
Subject: [PATCH] target/arm: register CPU features for property
|
||||
|
||||
The Arm architecture specifies a number of ID registers that are
|
||||
characterized as comprising a set of 4-bit ID fields. Each ID field
|
||||
identifies the presence, and possibly the level of support for, a
|
||||
particular feature in an implementation of the architecture. [1]
|
||||
|
||||
For most of the ID fields, there is a minimum presence value, equal to
|
||||
or higher than which means the corresponding CPU feature is implemented.
|
||||
Hence, we can use the minimum presence value to determine whether a CPU
|
||||
feature is enabled and enable a CPU feature.
|
||||
|
||||
To disable a CPU feature, setting the corresponding ID field to 0x0/0xf
|
||||
(for unsigned/signed field) seems as a good idea. However, it maybe
|
||||
lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID
|
||||
field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP
|
||||
(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the
|
||||
implementation of FPHP (half-precision floating-point). If
|
||||
ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also
|
||||
disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means
|
||||
not-implemented value) to disable a CPU feature safely.
|
||||
|
||||
[1] D13.1.3 Principles of the ID scheme for fields in ID registers in
|
||||
DDI.0487
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 343 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index f1ce0474a3..c081ecc12b 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -1211,6 +1211,347 @@ unsigned int gt_cntfrq_period_ns(ARMCPU *cpu)
|
||||
NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * CPUFeatureInfo:
|
||||
+ * @reg: The ID register where the ID field is in.
|
||||
+ * @name: The name of the CPU feature.
|
||||
+ * @length: The bit length of the ID field.
|
||||
+ * @shift: The bit shift of the ID field in the ID register.
|
||||
+ * @min_value: The minimum value equal to or larger than which means the CPU
|
||||
+ * feature is implemented.
|
||||
+ * @ni_value: Not-implemented value. It will be set to the ID field when
|
||||
+ * disabling the CPU feature. Usually, it's min_value - 1.
|
||||
+ * @sign: Whether the ID field is signed.
|
||||
+ * @is_32bit: Whether the CPU feature is for 32-bit.
|
||||
+ *
|
||||
+ * In ARM, a CPU feature is described by an ID field, which is a 4-bit field in
|
||||
+ * an ID register.
|
||||
+ */
|
||||
+typedef struct CPUFeatureInfo {
|
||||
+ CPUIDReg reg;
|
||||
+ const char *name;
|
||||
+ int length;
|
||||
+ int shift;
|
||||
+ int min_value;
|
||||
+ int ni_value;
|
||||
+ bool sign;
|
||||
+ bool is_32bit;
|
||||
+} CPUFeatureInfo;
|
||||
+
|
||||
+#define FIELD_INFO(feature_name, id_reg, field, s, min_val, ni_val, is32bit) { \
|
||||
+ .reg = id_reg, \
|
||||
+ .length = R_ ## id_reg ## _ ## field ## _LENGTH, \
|
||||
+ .shift = R_ ## id_reg ## _ ## field ## _SHIFT, \
|
||||
+ .sign = s, \
|
||||
+ .min_value = min_val, \
|
||||
+ .ni_value = ni_val, \
|
||||
+ .name = feature_name, \
|
||||
+ .is_32bit = is32bit, \
|
||||
+}
|
||||
+
|
||||
+static struct CPUFeatureInfo cpu_features[] = {
|
||||
+ FIELD_INFO("swap", ID_ISAR0, SWAP, false, 1, 0, true),
|
||||
+ FIELD_INFO("bitcount", ID_ISAR0, BITCOUNT, false, 1, 0, true),
|
||||
+ FIELD_INFO("bitfield", ID_ISAR0, BITFIELD, false, 1, 0, true),
|
||||
+ FIELD_INFO("cmpbranch", ID_ISAR0, CMPBRANCH, false, 1, 0, true),
|
||||
+ FIELD_INFO("coproc", ID_ISAR0, COPROC, false, 1, 0, true),
|
||||
+ FIELD_INFO("debug", ID_ISAR0, DEBUG, false, 1, 0, true),
|
||||
+ FIELD_INFO("device", ID_ISAR0, DIVIDE, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("endian", ID_ISAR1, ENDIAN, false, 1, 0, true),
|
||||
+ FIELD_INFO("except", ID_ISAR1, EXCEPT, false, 1, 0, true),
|
||||
+ FIELD_INFO("except_ar", ID_ISAR1, EXCEPT_AR, false, 1, 0, true),
|
||||
+ FIELD_INFO("extend", ID_ISAR1, EXTEND, false, 1, 0, true),
|
||||
+ FIELD_INFO("ifthen", ID_ISAR1, IFTHEN, false, 1, 0, true),
|
||||
+ FIELD_INFO("immediate", ID_ISAR1, IMMEDIATE, false, 1, 0, true),
|
||||
+ FIELD_INFO("interwork", ID_ISAR1, INTERWORK, false, 1, 0, true),
|
||||
+ FIELD_INFO("jazelle", ID_ISAR1, JAZELLE, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("loadstore", ID_ISAR2, LOADSTORE, false, 1, 0, true),
|
||||
+ FIELD_INFO("memhint", ID_ISAR2, MEMHINT, false, 1, 0, true),
|
||||
+ FIELD_INFO("multiaccessint", ID_ISAR2, MULTIACCESSINT, false, 1, 0, true),
|
||||
+ FIELD_INFO("mult", ID_ISAR2, MULT, false, 1, 0, true),
|
||||
+ FIELD_INFO("mults", ID_ISAR2, MULTS, false, 1, 0, true),
|
||||
+ FIELD_INFO("multu", ID_ISAR2, MULTU, false, 1, 0, true),
|
||||
+ FIELD_INFO("psr_ar", ID_ISAR2, PSR_AR, false, 1, 0, true),
|
||||
+ FIELD_INFO("reversal", ID_ISAR2, REVERSAL, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("saturate", ID_ISAR3, SATURATE, false, 1, 0, true),
|
||||
+ FIELD_INFO("simd", ID_ISAR3, SIMD, false, 1, 0, true),
|
||||
+ FIELD_INFO("svc", ID_ISAR3, SVC, false, 1, 0, true),
|
||||
+ FIELD_INFO("synchprim", ID_ISAR3, SYNCHPRIM, false, 1, 0, true),
|
||||
+ FIELD_INFO("tabbranch", ID_ISAR3, TABBRANCH, false, 1, 0, true),
|
||||
+ FIELD_INFO("t32copy", ID_ISAR3, T32COPY, false, 1, 0, true),
|
||||
+ FIELD_INFO("truenop", ID_ISAR3, TRUENOP, false, 1, 0, true),
|
||||
+ FIELD_INFO("t32ee", ID_ISAR3, T32EE, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("unpriv", ID_ISAR4, UNPRIV, false, 1, 0, true),
|
||||
+ FIELD_INFO("withshifts", ID_ISAR4, WITHSHIFTS, false, 1, 0, true),
|
||||
+ FIELD_INFO("writeback", ID_ISAR4, WRITEBACK, false, 1, 0, true),
|
||||
+ FIELD_INFO("smc", ID_ISAR4, SMC, false, 1, 0, true),
|
||||
+ FIELD_INFO("barrier", ID_ISAR4, BARRIER, false, 1, 0, true),
|
||||
+ FIELD_INFO("synchprim_frac", ID_ISAR4, SYNCHPRIM_FRAC, false, 1, 0, true),
|
||||
+ FIELD_INFO("psr_m", ID_ISAR4, PSR_M, false, 1, 0, true),
|
||||
+ FIELD_INFO("swp_frac", ID_ISAR4, SWP_FRAC, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("sevl", ID_ISAR5, SEVL, false, 1, 0, true),
|
||||
+ FIELD_INFO("aes", ID_ISAR5, AES, false, 1, 0, true),
|
||||
+ FIELD_INFO("sha1", ID_ISAR5, SHA1, false, 1, 0, true),
|
||||
+ FIELD_INFO("sha2", ID_ISAR5, SHA2, false, 1, 0, true),
|
||||
+ FIELD_INFO("crc32", ID_ISAR5, CRC32, false, 1, 0, true),
|
||||
+ FIELD_INFO("rdm", ID_ISAR5, RDM, false, 1, 0, true),
|
||||
+ FIELD_INFO("vcma", ID_ISAR5, VCMA, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("jscvt", ID_ISAR6, JSCVT, false, 1, 0, true),
|
||||
+ FIELD_INFO("dp", ID_ISAR6, DP, false, 1, 0, true),
|
||||
+ FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
|
||||
+ FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
|
||||
+ FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
|
||||
+ FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
|
||||
+ FIELD_INFO("bpmaint", ID_MMFR3, BPMAINT, false, 1, 0, true),
|
||||
+ FIELD_INFO("maintbcst", ID_MMFR3, MAINTBCST, false, 1, 0, true),
|
||||
+ FIELD_INFO("pan", ID_MMFR3, PAN, false, 1, 0, true),
|
||||
+ FIELD_INFO("cohwalk", ID_MMFR3, COHWALK, false, 1, 0, true),
|
||||
+ FIELD_INFO("cmemsz", ID_MMFR3, CMEMSZ, false, 1, 0, true),
|
||||
+ FIELD_INFO("supersec", ID_MMFR3, SUPERSEC, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("specsei", ID_MMFR4, SPECSEI, false, 1, 0, true),
|
||||
+ FIELD_INFO("ac2", ID_MMFR4, AC2, false, 1, 0, true),
|
||||
+ FIELD_INFO("xnx", ID_MMFR4, XNX, false, 1, 0, true),
|
||||
+ FIELD_INFO("cnp", ID_MMFR4, CNP, false, 1, 0, true),
|
||||
+ FIELD_INFO("hpds", ID_MMFR4, HPDS, false, 1, 0, true),
|
||||
+ FIELD_INFO("lsm", ID_MMFR4, LSM, false, 1, 0, true),
|
||||
+ FIELD_INFO("ccidx", ID_MMFR4, CCIDX, false, 1, 0, true),
|
||||
+ FIELD_INFO("evt", ID_MMFR4, EVT, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("simdreg", MVFR0, SIMDREG, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpsp", MVFR0, FPSP, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpdp", MVFR0, FPDP, false, 1, 0, true),
|
||||
+ FIELD_INFO("fptrap", MVFR0, FPTRAP, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpdivide", MVFR0, FPDIVIDE, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpsqrt", MVFR0, FPSQRT, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpshvec", MVFR0, FPSHVEC, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpround", MVFR0, FPROUND, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("fpftz", MVFR1, FPFTZ, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpdnan", MVFR1, FPDNAN, false, 1, 0, true),
|
||||
+ FIELD_INFO("simdls", MVFR1, SIMDLS, false, 1, 0, true),
|
||||
+ FIELD_INFO("simdint", MVFR1, SIMDINT, false, 1, 0, true),
|
||||
+ FIELD_INFO("simdsp", MVFR1, SIMDSP, false, 1, 0, true),
|
||||
+ FIELD_INFO("simdhp", MVFR1, SIMDHP, false, 1, 0, true),
|
||||
+ FIELD_INFO("fphp", MVFR1, FPHP, false, 1, 0, true),
|
||||
+ FIELD_INFO("simdfmac", MVFR1, SIMDFMAC, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("simdmisc", MVFR2, SIMDMISC, false, 1, 0, true),
|
||||
+ FIELD_INFO("fpmisc", MVFR2, FPMISC, false, 1, 0, true),
|
||||
+
|
||||
+ FIELD_INFO("debugver", ID_AA64DFR0, DEBUGVER, false, 1, 0, false),
|
||||
+ FIELD_INFO("tracever", ID_AA64DFR0, TRACEVER, false, 1, 0, false),
|
||||
+ FIELD_INFO("pmuver", ID_AA64DFR0, PMUVER, false, 1, 0, false),
|
||||
+ FIELD_INFO("brps", ID_AA64DFR0, BRPS, false, 1, 0, false),
|
||||
+ FIELD_INFO("wrps", ID_AA64DFR0, WRPS, false, 1, 0, false),
|
||||
+ FIELD_INFO("ctx_cmps", ID_AA64DFR0, CTX_CMPS, false, 1, 0, false),
|
||||
+ FIELD_INFO("pmsver", ID_AA64DFR0, PMSVER, false, 1, 0, false),
|
||||
+ FIELD_INFO("doublelock", ID_AA64DFR0, DOUBLELOCK, false, 1, 0, false),
|
||||
+ FIELD_INFO("tracefilt", ID_AA64DFR0, TRACEFILT, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
|
||||
+ FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
|
||||
+ FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
|
||||
+ FIELD_INFO("crc32", ID_AA64ISAR0, CRC32, false, 1, 0, false),
|
||||
+ FIELD_INFO("atomics", ID_AA64ISAR0, ATOMIC, false, 1, 0, false),
|
||||
+ FIELD_INFO("asimdrdm", ID_AA64ISAR0, RDM, false, 1, 0, false),
|
||||
+ FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
|
||||
+ FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
|
||||
+ FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
|
||||
+ FIELD_INFO("asimddp", ID_AA64ISAR0, DP, false, 1, 0, false),
|
||||
+ FIELD_INFO("asimdfhm", ID_AA64ISAR0, FHM, false, 1, 0, false),
|
||||
+ FIELD_INFO("flagm", ID_AA64ISAR0, TS, false, 1, 0, false),
|
||||
+ FIELD_INFO("tlb", ID_AA64ISAR0, TLB, false, 1, 0, false),
|
||||
+ FIELD_INFO("rng", ID_AA64ISAR0, RNDR, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("dcpop", ID_AA64ISAR1, DPB, false, 1, 0, false),
|
||||
+ FIELD_INFO("papa", ID_AA64ISAR1, APA, false, 1, 0, false),
|
||||
+ FIELD_INFO("api", ID_AA64ISAR1, API, false, 1, 0, false),
|
||||
+ FIELD_INFO("jscvt", ID_AA64ISAR1, JSCVT, false, 1, 0, false),
|
||||
+ FIELD_INFO("fcma", ID_AA64ISAR1, FCMA, false, 1, 0, false),
|
||||
+ FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
|
||||
+ FIELD_INFO("pacg", ID_AA64ISAR1, GPA, false, 1, 0, false),
|
||||
+ FIELD_INFO("gpi", ID_AA64ISAR1, GPI, false, 1, 0, false),
|
||||
+ FIELD_INFO("frint", ID_AA64ISAR1, FRINTTS, false, 1, 0, false),
|
||||
+ FIELD_INFO("sb", ID_AA64ISAR1, SB, false, 1, 0, false),
|
||||
+ FIELD_INFO("specres", ID_AA64ISAR1, SPECRES, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("el0", ID_AA64PFR0, EL0, false, 1, 0, false),
|
||||
+ FIELD_INFO("el1", ID_AA64PFR0, EL1, false, 1, 0, false),
|
||||
+ FIELD_INFO("el2", ID_AA64PFR0, EL2, false, 1, 0, false),
|
||||
+ FIELD_INFO("el3", ID_AA64PFR0, EL3, false, 1, 0, false),
|
||||
+ FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
|
||||
+ FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
|
||||
+ FIELD_INFO("gic", ID_AA64PFR0, GIC, false, 1, 0, false),
|
||||
+ FIELD_INFO("ras", ID_AA64PFR0, RAS, false, 1, 0, false),
|
||||
+ FIELD_INFO("sve", ID_AA64PFR0, SVE, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("bti", ID_AA64PFR1, BT, false, 1, 0, false),
|
||||
+ FIELD_INFO("ssbs", ID_AA64PFR1, SSBS, false, 1, 0, false),
|
||||
+ FIELD_INFO("mte", ID_AA64PFR1, MTE, false, 1, 0, false),
|
||||
+ FIELD_INFO("ras_frac", ID_AA64PFR1, RAS_FRAC, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("parange", ID_AA64MMFR0, PARANGE, false, 1, 0, false),
|
||||
+ FIELD_INFO("asidbits", ID_AA64MMFR0, ASIDBITS, false, 1, 0, false),
|
||||
+ FIELD_INFO("bigend", ID_AA64MMFR0, BIGEND, false, 1, 0, false),
|
||||
+ FIELD_INFO("snsmem", ID_AA64MMFR0, SNSMEM, false, 1, 0, false),
|
||||
+ FIELD_INFO("bigendel0", ID_AA64MMFR0, BIGENDEL0, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran16", ID_AA64MMFR0, TGRAN16, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran64", ID_AA64MMFR0, TGRAN64, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran4", ID_AA64MMFR0, TGRAN4, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran16_2", ID_AA64MMFR0, TGRAN16_2, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran64_2", ID_AA64MMFR0, TGRAN64_2, false, 1, 0, false),
|
||||
+ FIELD_INFO("tgran4_2", ID_AA64MMFR0, TGRAN4_2, false, 1, 0, false),
|
||||
+ FIELD_INFO("exs", ID_AA64MMFR0, EXS, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("hafdbs", ID_AA64MMFR1, HAFDBS, false, 1, 0, false),
|
||||
+ FIELD_INFO("vmidbits", ID_AA64MMFR1, VMIDBITS, false, 1, 0, false),
|
||||
+ FIELD_INFO("vh", ID_AA64MMFR1, VH, false, 1, 0, false),
|
||||
+ FIELD_INFO("hpds", ID_AA64MMFR1, HPDS, false, 1, 0, false),
|
||||
+ FIELD_INFO("lo", ID_AA64MMFR1, LO, false, 1, 0, false),
|
||||
+ FIELD_INFO("pan", ID_AA64MMFR1, PAN, false, 1, 0, false),
|
||||
+ FIELD_INFO("specsei", ID_AA64MMFR1, SPECSEI, false, 1, 0, false),
|
||||
+ FIELD_INFO("xnx", ID_AA64MMFR1, XNX, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("cnp", ID_AA64MMFR2, CNP, false, 1, 0, false),
|
||||
+ FIELD_INFO("uao", ID_AA64MMFR2, UAO, false, 1, 0, false),
|
||||
+ FIELD_INFO("lsm", ID_AA64MMFR2, LSM, false, 1, 0, false),
|
||||
+ FIELD_INFO("iesb", ID_AA64MMFR2, IESB, false, 1, 0, false),
|
||||
+ FIELD_INFO("varange", ID_AA64MMFR2, VARANGE, false, 1, 0, false),
|
||||
+ FIELD_INFO("ccidx", ID_AA64MMFR2, CCIDX, false, 1, 0, false),
|
||||
+ FIELD_INFO("nv", ID_AA64MMFR2, NV, false, 1, 0, false),
|
||||
+ FIELD_INFO("st", ID_AA64MMFR2, ST, false, 1, 0, false),
|
||||
+ FIELD_INFO("uscat", ID_AA64MMFR2, AT, false, 1, 0, false),
|
||||
+ FIELD_INFO("ids", ID_AA64MMFR2, IDS, false, 1, 0, false),
|
||||
+ FIELD_INFO("fwb", ID_AA64MMFR2, FWB, false, 1, 0, false),
|
||||
+ FIELD_INFO("ttl", ID_AA64MMFR2, TTL, false, 1, 0, false),
|
||||
+ FIELD_INFO("bbm", ID_AA64MMFR2, BBM, false, 1, 0, false),
|
||||
+ FIELD_INFO("evt", ID_AA64MMFR2, EVT, false, 1, 0, false),
|
||||
+ FIELD_INFO("e0pd", ID_AA64MMFR2, E0PD, false, 1, 0, false),
|
||||
+
|
||||
+ FIELD_INFO("copdbg", ID_DFR0, COPDBG, false, 1, 0, false),
|
||||
+ FIELD_INFO("copsdbg", ID_DFR0, COPSDBG, false, 1, 0, false),
|
||||
+ FIELD_INFO("mmapdbg", ID_DFR0, MMAPDBG, false, 1, 0, false),
|
||||
+ FIELD_INFO("coptrc", ID_DFR0, COPTRC, false, 1, 0, false),
|
||||
+ FIELD_INFO("mmaptrc", ID_DFR0, MMAPTRC, false, 1, 0, false),
|
||||
+ FIELD_INFO("mprofdbg", ID_DFR0, MPROFDBG, false, 1, 0, false),
|
||||
+ FIELD_INFO("perfmon", ID_DFR0, PERFMON, false, 1, 0, false),
|
||||
+ FIELD_INFO("tracefilt", ID_DFR0, TRACEFILT, false, 1, 0, false),
|
||||
+
|
||||
+ {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
|
||||
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
|
||||
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_TS_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR0_TS_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "flagm2", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_DPB_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR1_DPB_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "dcpodp", .is_32bit = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
|
||||
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
|
||||
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ ARMCPU *cpu = ARM_CPU(obj);
|
||||
+ CPUFeatureInfo *feat = opaque;
|
||||
+ int field_value = feat->sign ? sextract64(cpu->isar.regs[feat->reg],
|
||||
+ feat->shift, feat->length) :
|
||||
+ extract64(cpu->isar.regs[feat->reg],
|
||||
+ feat->shift, feat->length);
|
||||
+ bool value = field_value >= feat->min_value;
|
||||
+
|
||||
+ visit_type_bool(v, name, &value, errp);
|
||||
+}
|
||||
+
|
||||
+static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ DeviceState *dev = DEVICE(obj);
|
||||
+ ARMCPU *cpu = ARM_CPU(obj);
|
||||
+ ARMISARegisters *isar = &cpu->isar;
|
||||
+ CPUFeatureInfo *feat = opaque;
|
||||
+ Error *local_err = NULL;
|
||||
+ bool value;
|
||||
+
|
||||
+ if (dev->realized) {
|
||||
+ qdev_prop_set_after_realize(dev, name, errp);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ visit_type_bool(v, name, &value, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (value) {
|
||||
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||
+ feat->shift, feat->length,
|
||||
+ feat->min_value);
|
||||
+ } else {
|
||||
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
|
||||
+ feat->shift, feat->length,
|
||||
+ feat->ni_value);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void arm_cpu_register_feature_props(ARMCPU *cpu)
|
||||
+{
|
||||
+ int i;
|
||||
+ int num = ARRAY_SIZE(cpu_features);
|
||||
+ ObjectProperty *op;
|
||||
+ CPUARMState *env = &cpu->env;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ if ((arm_feature(env, ARM_FEATURE_AARCH64) && cpu_features[i].is_32bit)
|
||||
+ || (!arm_feature(env, ARM_FEATURE_AARCH64) &&
|
||||
+ cpu_features[i].is_32bit)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ op = object_property_find(OBJECT(cpu), cpu_features[i].name);
|
||||
+ if (!op) {
|
||||
+ object_property_add(OBJECT(cpu), cpu_features[i].name, "bool",
|
||||
+ arm_cpu_get_bit_prop,
|
||||
+ arm_cpu_set_bit_prop,
|
||||
+ NULL, &cpu_features[i]);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void arm_cpu_post_init(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@@ -1319,6 +1660,8 @@ void arm_cpu_post_init(Object *obj)
|
||||
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
|
||||
|
||||
+ arm_cpu_register_feature_props(cpu);
|
||||
+
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
|
||||
qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property);
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
31
tests-Disable-filemonitor-testcase.patch
Normal file
31
tests-Disable-filemonitor-testcase.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 4f09a1c2aa855aab666d729defce4c7f0466cb77 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Thu, 10 Feb 2022 17:16:55 +0800
|
||||
Subject: [PATCH] tests: Disable filemonitor testcase
|
||||
|
||||
Since filemonitor testcase requires that host kernel being a LTS version,
|
||||
we cannot guarantee that on OBS system. Lets disable it by default.
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
Signed-off-by: Jinhao Gao <gaojinhao@huawei.com>
|
||||
---
|
||||
tests/unit/meson.build | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
|
||||
index acac3622ed..c21d817874 100644
|
||||
--- a/tests/unit/meson.build
|
||||
+++ b/tests/unit/meson.build
|
||||
@@ -129,9 +129,6 @@ if have_system
|
||||
'test-vmstate': [migration, io],
|
||||
'test-yank': ['socket-helpers.c', qom, io, chardev]
|
||||
}
|
||||
- if 'CONFIG_INOTIFY1' in config_host
|
||||
- tests += {'test-util-filemonitor': []}
|
||||
- endif
|
||||
|
||||
# Some tests: test-char, test-qdev-global-props, and test-qga,
|
||||
# are not runnable under TSan due to a known issue.
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user