1
Hi,
1
From: Aleksandar Markovic <amarkovic@wavecomp.com>
2
2
3
This new version removed the translate_fn() from patch 1 because it
3
This is a collection of misc patches for Linux user that I recently
4
wasn't removing the sign-extension for pentry as we thought it would.
4
accumulated from variuous sources. All of them originate from problems
5
A more detailed explanation is given in the commit msg of patch 1.
5
observed on mips target. However, most of these changes actually
6
affect and fix linux-user problems on multiple targets.
6
7
7
We're now retrieving the 'lowaddr' value from load_elf_ram_sym() and
8
There are three checkpatch warninhs and two checkpatch errors that
8
using it when we're running a 32-bit CPU. This worked with 32 bit
9
sould be ignored in the given circumstances.
9
'virt' machine booting with the -kernel option.
10
10
11
If this approach doesn't work for the Xvisor use case, IMO we should
11
v11->v12:
12
just filter kernel_load_addr bits directly as we were doing a handful of
13
versions ago.
14
12
15
Patches are based on current riscv-to-apply.next.
13
- used the preffered Laurent's email address for linux-user
14
- added a note on checkpetch warnings and errors in the commit letter
15
16
16
17
Changes from v9:
17
v10->v11:
18
- patch 1:
19
- removed the translate_fn() callback
20
- return 'kernel_low' when running a 32-bit CPU
21
- v9 link: https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg04509.html
22
18
23
Daniel Henrique Barboza (3):
19
- patch on <ADD|DROP>_MEMEBERSHIP basically reverted to its first
24
hw/riscv: handle 32 bit CPUs kernel_addr in riscv_load_kernel()
20
version
25
hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()
21
- corrected patch on statx()
26
hw/riscv/boot.c: make riscv_load_initrd() static
22
- added patch on strace support for statx()
23
- added patch on fixing flock structure for MIPS O64 ABI
27
24
28
hw/riscv/boot.c | 96 +++++++++++++++++++++++---------------
25
v9->v10:
29
hw/riscv/microchip_pfsoc.c | 12 +----
26
30
hw/riscv/opentitan.c | 4 +-
27
- improved commit messages for patches 2 and 3
31
hw/riscv/sifive_e.c | 4 +-
28
32
hw/riscv/sifive_u.c | 12 +----
29
v8->v9:
33
hw/riscv/spike.c | 14 ++----
30
34
hw/riscv/virt.c | 12 +----
31
- fixed build error on some systems related to SOL_ALG
35
include/hw/riscv/boot.h | 3 +-
32
36
8 files changed, 76 insertions(+), 81 deletions(-)
33
v7->v8:
34
35
- added a patch on setsockopt() option SOL_ALG
36
37
v6->v7:
38
39
- fixed a build error for older kernels related to the patch on
40
setsockopt() options
41
- removed four patches that on the meantime got accepted into the
42
main source tree
43
44
v5->v6:
45
46
- fixed a mistake in patch #4
47
- improved commit messages in patches #4 and #6
48
49
v4->v5:
50
51
- added the patch on statx() support
52
- improved the patch on IPV6_<ADD|DROP>_MEMBERSHIP to take into
53
account the possibility of different names for a field
54
- minor corrections in commit messages
55
56
v3->v4:
57
58
- improved commit messages (fixed some typos, improved relevance)
59
60
v2->v3:
61
62
- updated and improved commit messages
63
- added IPV6_DROP_MEMBERSHIP support to the patch on setsockopt()'s
64
option
65
66
v1->v2:
67
68
- added the patch on setsockopt()'s option IPV6_ADD_MEMBERSHIP
69
- improved the commit messages
70
71
Aleksandar Markovic (1):
72
linux-user: Fix flock structure for MIPS O64 ABI
73
74
Aleksandar Rikalo (1):
75
linux-user: Add support for translation of statx() syscall
76
77
Jim Wilson (1):
78
linux-user: Add support for strace for statx() syscall
79
80
Neng Chen (1):
81
linux-user: Add support for setsockopt() options
82
IPV6_<ADD|DROP>_MEMBERSHIP
83
84
Yunqiang Su (1):
85
linux-user: Add support for setsockopt() option SOL_ALG
86
87
linux-user/generic/fcntl.h | 2 +-
88
linux-user/mips/target_fcntl.h | 4 +
89
linux-user/strace.c | 86 +++++++++++++++++++
90
linux-user/strace.list | 3 +
91
linux-user/syscall.c | 186 ++++++++++++++++++++++++++++++++++++++++-
92
linux-user/syscall_defs.h | 37 ++++++++
93
6 files changed, 316 insertions(+), 2 deletions(-)
37
94
38
--
95
--
39
2.39.1
96
2.7.4
97
98
diff view generated by jsdifflib
New patch
1
From: Neng Chen <nchen@wavecomp.com>
1
2
3
Add support for the option IPV6_<ADD|DROP>_MEMBERSHIP of the syscall
4
setsockopt(). This option controls membership in multicast groups.
5
Argument is a pointer to a struct ipv6_mreq.
6
7
The glibc <netinet/in.h> header defines the ipv6_mreq structure,
8
which includes the following members:
9
10
struct in6_addr ipv6mr_multiaddr;
11
unsigned int ipv6mr_interface;
12
13
Whereas the kernel in its <linux/in6.h> header defines following
14
members of the same structure:
15
16
struct in6_addr ipv6mr_multiaddr;
17
int ipv6mr_ifindex;
18
19
POSIX defines ipv6mr_interface [1].
20
21
__UAPI_DEF_IVP6_MREQ appears in kernel headers with v3.12:
22
23
cfd280c91253 net: sync some IP headers with glibc
24
25
Without __UAPI_DEF_IVP6_MREQ, kernel defines ipv6mr_ifindex, and
26
this is explained in cfd280c91253:
27
28
"If you include the kernel headers first you get those,
29
and if you include the glibc headers first you get those,
30
and the following patch arranges a coordination and
31
synchronization between the two."
32
33
So before 3.12, a program can't include both <netinet/in.h> and
34
<linux/in6.h>.
35
36
In linux-user/syscall.c, we only include <netinet/in.h> (glibc) and
37
not <linux/in6.h> (kernel headers), so ipv6mr_interface is the one
38
to use.
39
40
[1] http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netinet/in.h.html
41
42
Signed-off-by: Neng Chen <nchen@wavecomp.com>
43
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
44
---
45
linux-user/syscall.c | 19 +++++++++++++++++++
46
1 file changed, 19 insertions(+)
47
48
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/linux-user/syscall.c
51
+++ b/linux-user/syscall.c
52
@@ -XXX,XX +XXX,XX @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
53
&pki, sizeof(pki)));
54
break;
55
}
56
+ case IPV6_ADD_MEMBERSHIP:
57
+ case IPV6_DROP_MEMBERSHIP:
58
+ {
59
+ struct ipv6_mreq ipv6mreq;
60
+
61
+ if (optlen < sizeof(ipv6mreq)) {
62
+ return -TARGET_EINVAL;
63
+ }
64
+
65
+ if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
66
+ return -TARGET_EFAULT;
67
+ }
68
+
69
+ ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
70
+
71
+ ret = get_errno(setsockopt(sockfd, level, optname,
72
+ &ipv6mreq, sizeof(ipv6mreq)));
73
+ break;
74
+ }
75
default:
76
goto unimplemented;
77
}
78
--
79
2.7.4
80
81
diff view generated by jsdifflib
New patch
1
From: Yunqiang Su <ysu@wavecomp.com>
1
2
3
Add support for options SOL_ALG of the syscall setsockopt(). This
4
option is used in relation to Linux kernel Crypto API, and allows
5
a user to set additional information for the cipher operation via
6
syscall setsockopt(). The field "optname" must be one of the
7
following:
8
9
- ALG_SET_KEY – seting the key
10
- ALG_SET_AEAD_AUTHSIZE – set the authentication tag size
11
12
SOL_ALG is relatively newer setsockopt() option. Therefore, the
13
code that handles SOL_ALG is enclosed in "ifdef" so that the build
14
does not fail for older kernels that do not contain support for
15
SOL_ALG. "ifdef" also contains check if ALG_SET_KEY and
16
ALG_SET_AEAD_AUTHSIZE are defined.
17
18
Signed-off-by: Yunqiang Su <ysu@wavecomp.com>
19
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
20
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
21
---
22
linux-user/syscall.c | 31 +++++++++++++++++++++++++++++++
23
1 file changed, 31 insertions(+)
24
25
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/linux-user/syscall.c
28
+++ b/linux-user/syscall.c
29
@@ -XXX,XX +XXX,XX @@
30
#include <linux/blkpg.h>
31
#include <netpacket/packet.h>
32
#include <linux/netlink.h>
33
+#include <linux/if_alg.h>
34
#include "linux_loop.h"
35
#include "uname.h"
36
37
@@ -XXX,XX +XXX,XX @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
38
goto unimplemented;
39
}
40
break;
41
+#if defined(SOL_ALG) && defined(ALG_SET_KEY) && defined(ALG_SET_AEAD_AUTHSIZE)
42
+ case SOL_ALG:
43
+ switch (optname) {
44
+ case ALG_SET_KEY:
45
+ {
46
+ char *alg_key = g_malloc(optlen);
47
+
48
+ if (!alg_key) {
49
+ return -TARGET_ENOMEM;
50
+ }
51
+ if (copy_from_user(alg_key, optval_addr, optlen)) {
52
+ g_free(alg_key);
53
+ return -TARGET_EFAULT;
54
+ }
55
+ ret = get_errno(setsockopt(sockfd, level, optname,
56
+ alg_key, optlen));
57
+ g_free(alg_key);
58
+ break;
59
+ }
60
+ case ALG_SET_AEAD_AUTHSIZE:
61
+ {
62
+ ret = get_errno(setsockopt(sockfd, level, optname,
63
+ NULL, optlen));
64
+ break;
65
+ }
66
+ default:
67
+ goto unimplemented;
68
+ }
69
+ break;
70
+#endif
71
case TARGET_SOL_SOCKET:
72
switch (optname) {
73
case TARGET_SO_RCVTIMEO:
74
--
75
2.7.4
76
77
diff view generated by jsdifflib
1
The microchip_icicle_kit, sifive_u, spike and virt boards are now doing
1
From: Aleksandar Rikalo <arikalo@wavecomp.com>
2
the same steps when '-kernel' is used:
2
3
3
Implement support for translation of system call statx().
4
- execute load_kernel()
4
5
- load init_rd()
5
The implementation is based on "best effort" approach: if host is
6
- write kernel_cmdline
6
capable of executing statx(), host statx() is used. If not, the
7
7
implementation includes invoking other (more mature) system calls
8
Let's fold everything inside riscv_load_kernel() to avoid code
8
(from the same 'stat' family) on the host side to achieve as close
9
repetition. To not change the behavior of boards that aren't calling
9
as possible functionality.
10
riscv_load_init(), add an 'load_initrd' flag to riscv_load_kernel() and
10
11
allow these boards to opt out from initrd loading.
11
Support for statx() in kernel and glibc was, however, introduced
12
12
at different points of time (the difference is more than a year):
13
Cc: Palmer Dabbelt <palmer@dabbelt.com>
13
14
Reviewed-by: Bin Meng <bmeng@tinylab.org>
14
- kernel: Linux 4.11 (30 April 2017)
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
- glibc: glibc 2.28 (1 Aug 2018)
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
17
In this patch, the availability of statx() support is established
18
via __NR_statx (if it is defined, statx() is considered available).
19
This coincedes with statx() introduction in kernel.
20
21
However, the structure statx definition may not be available for hosts
22
with glibc older than 2.28 (it is, by design, to be defined in one of
23
glibc headers), even though the full statx() functionality may be
24
supported in kernel, if the kernel is not older than 4.11. Hence,
25
a structure "target_statx" is defined in this patch, to remove that
26
dependency on glibc headers, and to use statx() functionality as soon
27
as the host kernel is capable of supporting it. Such structure statx
28
definition is used for both target and host structures statx (of
29
course, this doesn't mean the endian arrangement is the same on
30
target and host, and endian conversion is done in all necessary
31
cases).
32
33
Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
34
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
17
---
35
---
18
hw/riscv/boot.c | 21 ++++++++++++++++++---
36
linux-user/syscall.c | 136 +++++++++++++++++++++++++++++++++++++++++++++-
19
hw/riscv/microchip_pfsoc.c | 11 +----------
37
linux-user/syscall_defs.h | 37 +++++++++++++
20
hw/riscv/opentitan.c | 3 ++-
38
2 files changed, 172 insertions(+), 1 deletion(-)
21
hw/riscv/sifive_e.c | 3 ++-
39
22
hw/riscv/sifive_u.c | 11 +----------
40
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
23
hw/riscv/spike.c | 11 +----------
24
hw/riscv/virt.c | 11 +----------
25
include/hw/riscv/boot.h | 1 +
26
8 files changed, 27 insertions(+), 45 deletions(-)
27
28
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
29
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/boot.c
42
--- a/linux-user/syscall.c
31
+++ b/hw/riscv/boot.c
43
+++ b/linux-user/syscall.c
32
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
44
@@ -XXX,XX +XXX,XX @@
33
target_ulong riscv_load_kernel(MachineState *machine,
45
#include <sys/times.h>
34
RISCVHartArrayState *harts,
46
#include <sys/shm.h>
35
target_ulong kernel_start_addr,
47
#include <sys/sem.h>
36
+ bool load_initrd,
48
+#include <sys/stat.h>
37
symbol_fn_t sym_cb)
49
#include <sys/statfs.h>
38
{
50
#include <utime.h>
39
const char *kernel_filename = machine->kernel_filename;
51
#include <sys/sysinfo.h>
40
uint64_t kernel_load_base, kernel_entry, kernel_low;
52
@@ -XXX,XX +XXX,XX @@ _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
41
+ void *fdt = machine->fdt;
53
unsigned long, idx1, unsigned long, idx2)
42
54
#endif
43
g_assert(kernel_filename != NULL);
55
44
56
+/*
45
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
57
+ * It is assumed that struct statx is architecture independent.
46
kernel_entry = kernel_low;
58
+ */
47
}
59
+#if defined(TARGET_NR_statx) && defined(__NR_statx)
48
60
+_syscall5(int, statx, int, dirfd, const char *, pathname, int, flags,
49
- return kernel_entry;
61
+ unsigned int, mask, struct target_statx *, statxbuf)
50
+ goto out;
62
+#endif
51
}
63
+
52
64
static bitmask_transtbl fcntl_flags_tbl[] = {
53
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
65
{ TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
54
NULL, NULL, NULL) > 0) {
66
{ TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
55
- return kernel_entry;
67
@@ -XXX,XX +XXX,XX @@ static inline abi_long host_to_target_stat64(void *cpu_env,
56
+ goto out;
68
}
57
}
69
#endif
58
70
59
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
71
+#if defined(TARGET_NR_statx) && defined(__NR_statx)
60
current_machine->ram_size, NULL) > 0) {
72
+static inline abi_long host_to_target_statx(struct target_statx *host_stx,
61
- return kernel_start_addr;
73
+ abi_ulong target_addr)
62
+ kernel_entry = kernel_start_addr;
74
+{
63
+ goto out;
75
+ struct target_statx *target_stx;
64
}
76
+
65
77
+ if (!lock_user_struct(VERIFY_WRITE, target_stx, target_addr, 0)) {
66
error_report("could not load kernel '%s'", kernel_filename);
78
+ return -TARGET_EFAULT;
67
exit(1);
68
+
69
+out:
70
+ if (load_initrd && machine->initrd_filename) {
71
+ riscv_load_initrd(machine, kernel_entry);
72
+ }
79
+ }
73
+
80
+ memset(target_stx, 0, sizeof(*target_stx));
74
+ if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
81
+
75
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
82
+ __put_user(host_stx->stx_mask, &target_stx->stx_mask);
76
+ machine->kernel_cmdline);
83
+ __put_user(host_stx->stx_blksize, &target_stx->stx_blksize);
77
+ }
84
+ __put_user(host_stx->stx_attributes, &target_stx->stx_attributes);
78
+
85
+ __put_user(host_stx->stx_nlink, &target_stx->stx_nlink);
79
+ return kernel_entry;
86
+ __put_user(host_stx->stx_uid, &target_stx->stx_uid);
80
}
87
+ __put_user(host_stx->stx_gid, &target_stx->stx_gid);
81
88
+ __put_user(host_stx->stx_mode, &target_stx->stx_mode);
82
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
89
+ __put_user(host_stx->stx_ino, &target_stx->stx_ino);
83
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
90
+ __put_user(host_stx->stx_size, &target_stx->stx_size);
91
+ __put_user(host_stx->stx_blocks, &target_stx->stx_blocks);
92
+ __put_user(host_stx->stx_attributes_mask, &target_stx->stx_attributes_mask);
93
+ __put_user(host_stx->stx_atime.tv_sec, &target_stx->stx_atime.tv_sec);
94
+ __put_user(host_stx->stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec);
95
+ __put_user(host_stx->stx_btime.tv_sec, &target_stx->stx_atime.tv_sec);
96
+ __put_user(host_stx->stx_btime.tv_nsec, &target_stx->stx_atime.tv_nsec);
97
+ __put_user(host_stx->stx_ctime.tv_sec, &target_stx->stx_atime.tv_sec);
98
+ __put_user(host_stx->stx_ctime.tv_nsec, &target_stx->stx_atime.tv_nsec);
99
+ __put_user(host_stx->stx_mtime.tv_sec, &target_stx->stx_atime.tv_sec);
100
+ __put_user(host_stx->stx_mtime.tv_nsec, &target_stx->stx_atime.tv_nsec);
101
+ __put_user(host_stx->stx_rdev_major, &target_stx->stx_rdev_major);
102
+ __put_user(host_stx->stx_rdev_minor, &target_stx->stx_rdev_minor);
103
+ __put_user(host_stx->stx_dev_major, &target_stx->stx_dev_major);
104
+ __put_user(host_stx->stx_dev_minor, &target_stx->stx_dev_minor);
105
+
106
+ unlock_user_struct(target_stx, target_addr, 1);
107
+
108
+ return 0;
109
+}
110
+#endif
111
+
112
+
113
/* ??? Using host futex calls even when target atomic operations
114
are not really atomic probably breaks things. However implementing
115
futexes locally would make futexes shared between multiple processes
116
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
117
abi_long ret;
118
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
119
|| defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
120
- || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
121
+ || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
122
+ || defined(TARGET_NR_statx)
123
struct stat st;
124
#endif
125
#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
126
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
127
ret = host_to_target_stat64(cpu_env, arg3, &st);
128
return ret;
129
#endif
130
+#if defined(TARGET_NR_statx)
131
+ case TARGET_NR_statx:
132
+ {
133
+ struct target_statx *target_stx;
134
+ int dirfd = arg1;
135
+ int flags = arg3;
136
+
137
+ p = lock_user_string(arg2);
138
+ if (p == NULL) {
139
+ return -TARGET_EFAULT;
140
+ }
141
+#if defined(__NR_statx)
142
+ {
143
+ /*
144
+ * It is assumed that struct statx is architecture independent.
145
+ */
146
+ struct target_statx host_stx;
147
+ int mask = arg4;
148
+
149
+ ret = get_errno(statx(dirfd, p, flags, mask, &host_stx));
150
+ if (!is_error(ret)) {
151
+ if (host_to_target_statx(&host_stx, arg5) != 0) {
152
+ unlock_user(p, arg2, 0);
153
+ return -TARGET_EFAULT;
154
+ }
155
+ }
156
+
157
+ if (ret != -TARGET_ENOSYS) {
158
+ unlock_user(p, arg2, 0);
159
+ return ret;
160
+ }
161
+ }
162
+#endif
163
+ if (*((char *)p) == 0) {
164
+ /*
165
+ * By file descriptor
166
+ */
167
+ if (flags & AT_EMPTY_PATH) {
168
+ unlock_user(p, arg2, 0);
169
+ return -TARGET_ENOENT;
170
+ }
171
+ ret = get_errno(fstat(dirfd, &st));
172
+ } else if (*((char *)p) == '/') {
173
+ /*
174
+ * By absolute pathname
175
+ */
176
+ ret = get_errno(stat(path(p), &st));
177
+ } else {
178
+ /*
179
+ * By pathname relative to the current working directory
180
+ * (if 'dirfd' is AT_FDCWD) or relative to the directory
181
+ * referred to by the file descriptor 'dirfd'.
182
+ */
183
+ ret = get_errno(fstatat(dirfd, path(p), &st, flags));
184
+ }
185
+ unlock_user(p, arg2, 0);
186
+
187
+ if (!is_error(ret)) {
188
+ if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
189
+ return -TARGET_EFAULT;
190
+ }
191
+ memset(target_stx, 0, sizeof(*target_stx));
192
+ __put_user(major(st.st_dev), &target_stx->stx_dev_major);
193
+ __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
194
+ __put_user(st.st_ino, &target_stx->stx_ino);
195
+ __put_user(st.st_mode, &target_stx->stx_mode);
196
+ __put_user(st.st_uid, &target_stx->stx_uid);
197
+ __put_user(st.st_gid, &target_stx->stx_gid);
198
+ __put_user(st.st_nlink, &target_stx->stx_nlink);
199
+ __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
200
+ __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
201
+ __put_user(st.st_size, &target_stx->stx_size);
202
+ __put_user(st.st_blksize, &target_stx->stx_blksize);
203
+ __put_user(st.st_blocks, &target_stx->stx_blocks);
204
+ __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
205
+ __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
206
+ __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
207
+ unlock_user_struct(target_stx, arg5, 1);
208
+ }
209
+ }
210
+ return ret;
211
+#endif
212
#ifdef TARGET_NR_lchown
213
case TARGET_NR_lchown:
214
if (!(p = lock_user_string(arg1)))
215
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
84
index XXXXXXX..XXXXXXX 100644
216
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/riscv/microchip_pfsoc.c
217
--- a/linux-user/syscall_defs.h
86
+++ b/hw/riscv/microchip_pfsoc.c
218
+++ b/linux-user/syscall_defs.h
87
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
219
@@ -XXX,XX +XXX,XX @@ struct target_user_cap_data {
88
firmware_end_addr);
220
/* Return size of the log buffer */
89
221
#define TARGET_SYSLOG_ACTION_SIZE_BUFFER 10
90
kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
222
91
- kernel_start_addr, NULL);
223
+struct target_statx_timestamp {
92
-
224
+ int64_t tv_sec;
93
- if (machine->initrd_filename) {
225
+ uint32_t tv_nsec;
94
- riscv_load_initrd(machine, kernel_entry);
226
+ int32_t __reserved;
95
- }
227
+};
96
-
228
+
97
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
229
+struct target_statx {
98
- qemu_fdt_setprop_string(machine->fdt, "/chosen",
230
+ /* 0x00 */
99
- "bootargs", machine->kernel_cmdline);
231
+ uint32_t stx_mask; /* What results were written [uncond] */
100
- }
232
+ uint32_t stx_blksize; /* Preferred general I/O size [uncond] */
101
+ kernel_start_addr, true, NULL);
233
+ uint64_t stx_attributes; /* Flags conveying information about the file */
102
234
+ /* 0x10 */
103
/* Compute the fdt load address in dram */
235
+ uint32_t stx_nlink; /* Number of hard links */
104
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
236
+ uint32_t stx_uid; /* User ID of owner */
105
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
237
+ uint32_t stx_gid; /* Group ID of owner */
106
index XXXXXXX..XXXXXXX 100644
238
+ uint16_t stx_mode; /* File mode */
107
--- a/hw/riscv/opentitan.c
239
+ uint16_t __spare0[1];
108
+++ b/hw/riscv/opentitan.c
240
+ /* 0x20 */
109
@@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine)
241
+ uint64_t stx_ino; /* Inode number */
110
242
+ uint64_t stx_size; /* File size */
111
if (machine->kernel_filename) {
243
+ uint64_t stx_blocks; /* Number of 512-byte blocks allocated */
112
riscv_load_kernel(machine, &s->soc.cpus,
244
+ uint64_t stx_attributes_mask; /* Mask to show what is supported */
113
- memmap[IBEX_DEV_RAM].base, NULL);
245
+ /* 0x40 */
114
+ memmap[IBEX_DEV_RAM].base,
246
+ struct target_statx_timestamp stx_atime; /* Last access time */
115
+ false, NULL);
247
+ struct target_statx_timestamp stx_btime; /* File creation time */
116
}
248
+ struct target_statx_timestamp stx_ctime; /* Last attribute change time */
117
}
249
+ struct target_statx_timestamp stx_mtime; /* Last data modification time */
118
250
+ /* 0x80 */
119
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
251
+ uint32_t stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
120
index XXXXXXX..XXXXXXX 100644
252
+ uint32_t stx_rdev_minor;
121
--- a/hw/riscv/sifive_e.c
253
+ uint32_t stx_dev_major; /* ID of device containing file [uncond] */
122
+++ b/hw/riscv/sifive_e.c
254
+ uint32_t stx_dev_minor;
123
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
255
+ /* 0x90 */
124
256
+ uint64_t __spare2[14]; /* Spare space for future expansion */
125
if (machine->kernel_filename) {
257
+ /* 0x100 */
126
riscv_load_kernel(machine, &s->soc.cpus,
258
+};
127
- memmap[SIFIVE_E_DEV_DTIM].base, NULL);
259
+
128
+ memmap[SIFIVE_E_DEV_DTIM].base,
260
#endif
129
+ false, NULL);
130
}
131
}
132
133
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/riscv/sifive_u.c
136
+++ b/hw/riscv/sifive_u.c
137
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
138
firmware_end_addr);
139
140
kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
141
- kernel_start_addr, NULL);
142
-
143
- if (machine->initrd_filename) {
144
- riscv_load_initrd(machine, kernel_entry);
145
- }
146
-
147
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
148
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
149
- machine->kernel_cmdline);
150
- }
151
+ kernel_start_addr, true, NULL);
152
} else {
153
/*
154
* If dynamic firmware is used, it doesn't know where is the next mode
155
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/riscv/spike.c
158
+++ b/hw/riscv/spike.c
159
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
160
161
kernel_entry = riscv_load_kernel(machine, &s->soc[0],
162
kernel_start_addr,
163
- htif_symbol_callback);
164
-
165
- if (machine->initrd_filename) {
166
- riscv_load_initrd(machine, kernel_entry);
167
- }
168
-
169
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
170
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
171
- machine->kernel_cmdline);
172
- }
173
+ true, htif_symbol_callback);
174
} else {
175
/*
176
* If dynamic firmware is used, it doesn't know where is the next mode
177
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/hw/riscv/virt.c
180
+++ b/hw/riscv/virt.c
181
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
182
firmware_end_addr);
183
184
kernel_entry = riscv_load_kernel(machine, &s->soc[0],
185
- kernel_start_addr, NULL);
186
-
187
- if (machine->initrd_filename) {
188
- riscv_load_initrd(machine, kernel_entry);
189
- }
190
-
191
- if (machine->kernel_cmdline && *machine->kernel_cmdline) {
192
- qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
193
- machine->kernel_cmdline);
194
- }
195
+ kernel_start_addr, true, NULL);
196
} else {
197
/*
198
* If dynamic firmware is used, it doesn't know where is the next mode
199
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
200
index XXXXXXX..XXXXXXX 100644
201
--- a/include/hw/riscv/boot.h
202
+++ b/include/hw/riscv/boot.h
203
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
204
target_ulong riscv_load_kernel(MachineState *machine,
205
RISCVHartArrayState *harts,
206
target_ulong firmware_end_addr,
207
+ bool load_initrd,
208
symbol_fn_t sym_cb);
209
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
210
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
211
--
261
--
212
2.39.1
262
2.7.4
263
264
diff view generated by jsdifflib
1
The only remaining caller is riscv_load_kernel_and_initrd() which
1
From: Jim Wilson <jimw@sifive.com>
2
belongs to the same file.
3
2
4
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
3
All of the flags need to be conditional as old systems don't have statx
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
support. Otherwise it works the same as other stat family syscalls.
6
Reviewed-by: Bin Meng <bmeng@tinylab.org>
5
This requires the pending patch to add statx support.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
7
Tested on Ubuntu 16.04 (no host statx) and Ubuntu 19.04 (with host statx)
8
using a riscv32-linux toolchain.
9
10
Signed-off-by: Jim Wilson <jimw@sifive.com>
11
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
12
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
8
---
13
---
9
hw/riscv/boot.c | 80 ++++++++++++++++++++---------------------
14
linux-user/strace.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
include/hw/riscv/boot.h | 1 -
15
linux-user/strace.list | 3 ++
11
2 files changed, 40 insertions(+), 41 deletions(-)
16
2 files changed, 89 insertions(+)
12
17
13
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
18
diff --git a/linux-user/strace.c b/linux-user/strace.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/riscv/boot.c
20
--- a/linux-user/strace.c
16
+++ b/hw/riscv/boot.c
21
+++ b/linux-user/strace.c
17
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
22
@@ -XXX,XX +XXX,XX @@ UNUSED static struct flags msg_flags[] = {
18
exit(1);
23
FLAG_END,
24
};
25
26
+UNUSED static struct flags statx_flags[] = {
27
+#ifdef AT_EMPTY_PATH
28
+ FLAG_GENERIC(AT_EMPTY_PATH),
29
+#endif
30
+#ifdef AT_NO_AUTOMOUNT
31
+ FLAG_GENERIC(AT_NO_AUTOMOUNT),
32
+#endif
33
+#ifdef AT_SYMLINK_NOFOLLOW
34
+ FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
35
+#endif
36
+#ifdef AT_STATX_SYNC_AS_STAT
37
+ FLAG_GENERIC(AT_STATX_SYNC_AS_STAT),
38
+#endif
39
+#ifdef AT_STATX_FORCE_SYNC
40
+ FLAG_GENERIC(AT_STATX_FORCE_SYNC),
41
+#endif
42
+#ifdef AT_STATX_DONT_SYNC
43
+ FLAG_GENERIC(AT_STATX_DONT_SYNC),
44
+#endif
45
+ FLAG_END,
46
+};
47
+
48
+UNUSED static struct flags statx_mask[] = {
49
+/* This must come first, because it includes everything. */
50
+#ifdef STATX_ALL
51
+ FLAG_GENERIC(STATX_ALL),
52
+#endif
53
+/* This must come second; it includes everything except STATX_BTIME. */
54
+#ifdef STATX_BASIC_STATS
55
+ FLAG_GENERIC(STATX_BASIC_STATS),
56
+#endif
57
+#ifdef STATX_TYPE
58
+ FLAG_GENERIC(STATX_TYPE),
59
+#endif
60
+#ifdef STATX_MODE
61
+ FLAG_GENERIC(STATX_MODE),
62
+#endif
63
+#ifdef STATX_NLINK
64
+ FLAG_GENERIC(STATX_NLINK),
65
+#endif
66
+#ifdef STATX_UID
67
+ FLAG_GENERIC(STATX_UID),
68
+#endif
69
+#ifdef STATX_GID
70
+ FLAG_GENERIC(STATX_GID),
71
+#endif
72
+#ifdef STATX_ATIME
73
+ FLAG_GENERIC(STATX_ATIME),
74
+#endif
75
+#ifdef STATX_MTIME
76
+ FLAG_GENERIC(STATX_MTIME),
77
+#endif
78
+#ifdef STATX_CTIME
79
+ FLAG_GENERIC(STATX_CTIME),
80
+#endif
81
+#ifdef STATX_INO
82
+ FLAG_GENERIC(STATX_INO),
83
+#endif
84
+#ifdef STATX_SIZE
85
+ FLAG_GENERIC(STATX_SIZE),
86
+#endif
87
+#ifdef STATX_BLOCKS
88
+ FLAG_GENERIC(STATX_BLOCKS),
89
+#endif
90
+#ifdef STATX_BTIME
91
+ FLAG_GENERIC(STATX_BTIME),
92
+#endif
93
+ FLAG_END,
94
+};
95
+
96
/*
97
* print_xxx utility functions. These are used to print syscall
98
* parameters in certain format. All of these have parameter
99
@@ -XXX,XX +XXX,XX @@ print_tgkill(const struct syscallname *name,
19
}
100
}
20
101
#endif
21
+static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
102
103
+#ifdef TARGET_NR_statx
104
+static void
105
+print_statx(const struct syscallname *name,
106
+ abi_long arg0, abi_long arg1, abi_long arg2,
107
+ abi_long arg3, abi_long arg4, abi_long arg5)
22
+{
108
+{
23
+ const char *filename = machine->initrd_filename;
109
+ print_syscall_prologue(name);
24
+ uint64_t mem_size = machine->ram_size;
110
+ print_at_dirfd(arg0, 0);
25
+ void *fdt = machine->fdt;
111
+ print_string(arg1, 0);
26
+ hwaddr start, end;
112
+ print_flags(statx_flags, arg2, 0);
27
+ ssize_t size;
113
+ print_flags(statx_mask, arg3, 0);
114
+ print_pointer(arg4, 1);
115
+ print_syscall_epilogue(name);
116
+}
117
+#endif
28
+
118
+
29
+ g_assert(filename != NULL);
30
+
31
+ /*
32
+ * We want to put the initrd far enough into RAM that when the
33
+ * kernel is uncompressed it will not clobber the initrd. However
34
+ * on boards without much RAM we must ensure that we still leave
35
+ * enough room for a decent sized initrd, and on boards with large
36
+ * amounts of RAM we must avoid the initrd being so far up in RAM
37
+ * that it is outside lowmem and inaccessible to the kernel.
38
+ * So for boards with less than 256MB of RAM we put the initrd
39
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
40
+ * the initrd at 128MB.
41
+ */
42
+ start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
43
+
44
+ size = load_ramdisk(filename, start, mem_size - start);
45
+ if (size == -1) {
46
+ size = load_image_targphys(filename, start, mem_size - start);
47
+ if (size == -1) {
48
+ error_report("could not load ramdisk '%s'", filename);
49
+ exit(1);
50
+ }
51
+ }
52
+
53
+ /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
54
+ if (fdt) {
55
+ end = start + size;
56
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
57
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
58
+ }
59
+}
60
+
61
target_ulong riscv_load_kernel(MachineState *machine,
62
RISCVHartArrayState *harts,
63
target_ulong kernel_start_addr,
64
@@ -XXX,XX +XXX,XX @@ out:
65
return kernel_entry;
66
}
67
68
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
69
-{
70
- const char *filename = machine->initrd_filename;
71
- uint64_t mem_size = machine->ram_size;
72
- void *fdt = machine->fdt;
73
- hwaddr start, end;
74
- ssize_t size;
75
-
76
- g_assert(filename != NULL);
77
-
78
- /*
79
- * We want to put the initrd far enough into RAM that when the
80
- * kernel is uncompressed it will not clobber the initrd. However
81
- * on boards without much RAM we must ensure that we still leave
82
- * enough room for a decent sized initrd, and on boards with large
83
- * amounts of RAM we must avoid the initrd being so far up in RAM
84
- * that it is outside lowmem and inaccessible to the kernel.
85
- * So for boards with less than 256MB of RAM we put the initrd
86
- * halfway into RAM, and for boards with 256MB of RAM or more we put
87
- * the initrd at 128MB.
88
- */
89
- start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
90
-
91
- size = load_ramdisk(filename, start, mem_size - start);
92
- if (size == -1) {
93
- size = load_image_targphys(filename, start, mem_size - start);
94
- if (size == -1) {
95
- error_report("could not load ramdisk '%s'", filename);
96
- exit(1);
97
- }
98
- }
99
-
100
- /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
101
- if (fdt) {
102
- end = start + size;
103
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
104
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
105
- }
106
-}
107
-
108
/*
119
/*
109
* This function makes an assumption that the DRAM interval
120
* An array of all of the syscalls we know about
110
* 'dram_base' + 'dram_size' is contiguous.
121
*/
111
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
122
diff --git a/linux-user/strace.list b/linux-user/strace.list
112
index XXXXXXX..XXXXXXX 100644
123
index XXXXXXX..XXXXXXX 100644
113
--- a/include/hw/riscv/boot.h
124
--- a/linux-user/strace.list
114
+++ b/include/hw/riscv/boot.h
125
+++ b/linux-user/strace.list
115
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
126
@@ -XXX,XX +XXX,XX @@
116
target_ulong firmware_end_addr,
127
#ifdef TARGET_NR_atomic_barrier
117
bool load_initrd,
128
{ TARGET_NR_atomic_barrier, "atomic_barrier", NULL, NULL, NULL },
118
symbol_fn_t sym_cb);
129
#endif
119
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
130
+#ifdef TARGET_NR_statx
120
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
131
+{ TARGET_NR_statx, "statx", NULL, print_statx, NULL },
121
MachineState *ms);
132
+#endif
122
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
123
--
133
--
124
2.39.1
134
2.7.4
125
135
126
136
diff view generated by jsdifflib
1
load_elf_ram_sym() will sign-extend 32 bit addresses. If a 32 bit QEMU
1
From: Aleksandar Markovic <amarkovic@wavecomp.com>
2
guest happens to be running in a hypervisor that are using 64 bits to
3
encode its address, kernel_entry can be padded with '1's and create
4
problems [1].
5
2
6
Using a translate_fn() callback in load_elf_ram_sym() to filter the
3
Only MIPS O32 and N32 have special (different than other
7
padding from the address doesn't work. A more detailed explanation can
4
architectures) definition of structure flock in kernel.
8
be found in [2]. The short version is that glue(load_elf, SZ), from
9
include/hw/elf_ops.h, will calculate 'pentry' (mapped into the
10
'kernel_load_base' var in riscv_load_Kernel()) before using
11
translate_fn(), and will not recalculate it after executing it. This
12
means that the callback does not prevent the padding from
13
kernel_load_base to appear.
14
5
15
Let's instead use a kernel_low var to capture the 'lowaddr' value from
6
Bring flock definition for MIPS O64 ABI to the correct state.
16
load_elf_ram_sim(), and return it when we're dealing with 32 bit CPUs.
17
7
18
[1] https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg02281.html
8
Reported-by: Dragan Mladjenovic <dmladjenovic@wavecomp.com>
19
[2] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg00099.html
9
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
10
---
11
linux-user/generic/fcntl.h | 2 +-
12
linux-user/mips/target_fcntl.h | 4 ++++
13
2 files changed, 5 insertions(+), 1 deletion(-)
20
14
21
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
diff --git a/linux-user/generic/fcntl.h b/linux-user/generic/fcntl.h
22
---
16
index XXXXXXX..XXXXXXX 100644
23
hw/riscv/boot.c | 15 +++++++++++----
17
--- a/linux-user/generic/fcntl.h
24
hw/riscv/microchip_pfsoc.c | 3 ++-
18
+++ b/linux-user/generic/fcntl.h
25
hw/riscv/opentitan.c | 3 ++-
19
@@ -XXX,XX +XXX,XX @@ struct target_flock {
26
hw/riscv/sifive_e.c | 3 ++-
20
short l_whence;
27
hw/riscv/sifive_u.c | 3 ++-
21
abi_long l_start;
28
hw/riscv/spike.c | 3 ++-
22
abi_long l_len;
29
hw/riscv/virt.c | 3 ++-
23
-#if defined(TARGET_MIPS)
30
include/hw/riscv/boot.h | 1 +
24
+#if defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32)
31
8 files changed, 24 insertions(+), 10 deletions(-)
25
abi_long l_sysid;
26
#endif
27
int l_pid;
28
diff --git a/linux-user/mips/target_fcntl.h b/linux-user/mips/target_fcntl.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/linux-user/mips/target_fcntl.h
31
+++ b/linux-user/mips/target_fcntl.h
32
@@ -XXX,XX +XXX,XX @@
33
#define TARGET_F_SETOWN 24 /* for sockets. */
34
#define TARGET_F_GETOWN 23 /* for sockets. */
35
36
+#if (TARGET_ABI_BITS == 32)
37
#define TARGET_ARCH_FLOCK_PAD abi_long pad[4];
38
+#else
39
+#define TARGET_ARCH_FLOCK_PAD
40
+#endif
41
#define TARGET_ARCH_FLOCK64_PAD
42
43
#define TARGET_F_GETLK64 33 /* using 'struct flock64' */
44
--
45
2.7.4
32
46
33
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
47
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/riscv/boot.c
36
+++ b/hw/riscv/boot.c
37
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
38
}
39
40
target_ulong riscv_load_kernel(MachineState *machine,
41
+ RISCVHartArrayState *harts,
42
target_ulong kernel_start_addr,
43
symbol_fn_t sym_cb)
44
{
45
const char *kernel_filename = machine->kernel_filename;
46
- uint64_t kernel_load_base, kernel_entry;
47
+ uint64_t kernel_load_base, kernel_entry, kernel_low;
48
49
g_assert(kernel_filename != NULL);
50
51
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
52
* the (expected) load address load address. This allows kernels to have
53
* separate SBI and ELF entry points (used by FreeBSD, for example).
54
*/
55
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
56
- NULL, &kernel_load_base, NULL, NULL, 0,
57
+ if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, NULL,
58
+ &kernel_load_base, &kernel_low, NULL, 0,
59
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
60
- return kernel_load_base;
61
+ kernel_entry = kernel_load_base;
62
+
63
+ if (riscv_is_32bit(harts)) {
64
+ kernel_entry = kernel_low;
65
+ }
66
+
67
+ return kernel_entry;
68
}
69
70
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
71
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/riscv/microchip_pfsoc.c
74
+++ b/hw/riscv/microchip_pfsoc.c
75
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
76
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
77
firmware_end_addr);
78
79
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
80
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
81
+ kernel_start_addr, NULL);
82
83
if (machine->initrd_filename) {
84
riscv_load_initrd(machine, kernel_entry);
85
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/riscv/opentitan.c
88
+++ b/hw/riscv/opentitan.c
89
@@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine)
90
}
91
92
if (machine->kernel_filename) {
93
- riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL);
94
+ riscv_load_kernel(machine, &s->soc.cpus,
95
+ memmap[IBEX_DEV_RAM].base, NULL);
96
}
97
}
98
99
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/riscv/sifive_e.c
102
+++ b/hw/riscv/sifive_e.c
103
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
104
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
105
106
if (machine->kernel_filename) {
107
- riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL);
108
+ riscv_load_kernel(machine, &s->soc.cpus,
109
+ memmap[SIFIVE_E_DEV_DTIM].base, NULL);
110
}
111
}
112
113
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/riscv/sifive_u.c
116
+++ b/hw/riscv/sifive_u.c
117
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
118
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
119
firmware_end_addr);
120
121
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
122
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
123
+ kernel_start_addr, NULL);
124
125
if (machine->initrd_filename) {
126
riscv_load_initrd(machine, kernel_entry);
127
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/hw/riscv/spike.c
130
+++ b/hw/riscv/spike.c
131
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
132
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
133
firmware_end_addr);
134
135
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr,
136
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
137
+ kernel_start_addr,
138
htif_symbol_callback);
139
140
if (machine->initrd_filename) {
141
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/riscv/virt.c
144
+++ b/hw/riscv/virt.c
145
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
146
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
147
firmware_end_addr);
148
149
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
150
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
151
+ kernel_start_addr, NULL);
152
153
if (machine->initrd_filename) {
154
riscv_load_initrd(machine, kernel_entry);
155
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
156
index XXXXXXX..XXXXXXX 100644
157
--- a/include/hw/riscv/boot.h
158
+++ b/include/hw/riscv/boot.h
159
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
160
hwaddr firmware_load_addr,
161
symbol_fn_t sym_cb);
162
target_ulong riscv_load_kernel(MachineState *machine,
163
+ RISCVHartArrayState *harts,
164
target_ulong firmware_end_addr,
165
symbol_fn_t sym_cb);
166
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
167
--
168
2.39.1
diff view generated by jsdifflib