Skip to content

Commit 619566c

Browse files
committed
userlib: alter handling of r7 in workaround
This completes the sequence of workarounds for: rust-lang/rust#73450 r7 is the frame pointer. asm! cannot reason about clobbers of r7. It tries to statically refuse it, but statically refuses r11 instead. This avoids clobbering r7.
1 parent 3d44fe4 commit 619566c

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

userlib/src/lib.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,51 @@ enum Sysnum {
5959
/// Wrap up the boilerplate involved in writing a syscall stub. Provide this
6060
/// macro the name of your `Sysnum` value, and the asm constraints. See below
6161
/// for examples.
62+
///
63+
/// We're having to handle r7 with kid gloves here. If you specify a constraint
64+
/// for r7, please specify it FIRST.
6265
macro_rules! syscall_asm {
66+
// R7 as input case
67+
($sysnum:expr, in("r7") $r7:expr, $($args:tt)*) => {
68+
asm!("
69+
mov {save11}, r11
70+
mov {save7}, r7
71+
mov r11, {sysnum}
72+
mov r7, {in7}
73+
svc #0
74+
mov r11, {save11}
75+
mov r7, {save7}
76+
",
77+
save11 = out(reg) _,
78+
save7 = out(reg) _,
79+
sysnum = const $sysnum as u32,
80+
81+
in7 = in(reg) $r7,
82+
83+
$($args)*
84+
);
85+
};
86+
// R7 as output case
87+
($sysnum:expr, lateout("r7") $r7:expr, $($args:tt)*) => {
88+
asm!("
89+
mov {save11}, r11
90+
mov {save7}, r7
91+
mov r11, {sysnum}
92+
svc #0
93+
mov r11, {save11}
94+
mov {out7}, r7
95+
mov r7, {save7}
96+
",
97+
save11 = out(reg) _,
98+
save7 = out(reg) _,
99+
sysnum = const $sysnum as u32,
100+
101+
out7 = lateout(reg) $r7,
102+
103+
$($args)*
104+
);
105+
};
106+
// R7 not used case
63107
($sysnum:expr, $($args:tt)*) => {
64108
asm!("
65109
mov {save11}, r11
@@ -88,10 +132,12 @@ pub fn sys_send(
88132
syscall_asm!(
89133
Sysnum::Send,
90134

135+
// r7 must be first, see syscall_asm
136+
in("r7") incoming.as_mut_ptr(),
137+
91138
inlateout("r4") u32::from(target.0) << 16 | u32::from(operation) => response_code,
92139
inlateout("r5") outgoing.as_ptr() => response_len,
93140
in("r6") outgoing.len(),
94-
in("r7") incoming.as_mut_ptr(),
95141
in("r8") incoming.len(),
96142
in("r9") leases.as_ptr(),
97143
in("r10") leases.len(),
@@ -113,10 +159,12 @@ pub fn sys_recv(buffer: &mut [u8], notification_mask: u32) -> RecvMessage {
113159
syscall_asm!(
114160
Sysnum::Recv,
115161

162+
// r7 must be first, see syscall_asm
163+
lateout("r7") message_len,
164+
116165
inlateout("r4") buffer.as_mut_ptr() => _,
117166
inlateout("r5") buffer.len() => sender,
118167
inlateout("r6") notification_mask => operation,
119-
lateout("r7") message_len,
120168
lateout("r8") response_capacity,
121169
lateout("r9") lease_count,
122170

@@ -146,12 +194,14 @@ pub fn sys_reply(peer: TaskId, code: u32, message: &[u8]) {
146194
syscall_asm!(
147195
Sysnum::Reply,
148196

197+
// r7 must be first, see syscall_asm
198+
in("r7") message.len(),
199+
149200
// While r4/r5 are not useful outputs at this time, they are
150201
// reserved as clobbered in case we change that.
151202
inlateout("r4") peer.0 as u32 => _,
152203
inlateout("r5") code => _,
153204
in("r6") message.as_ptr(),
154-
in("r7") message.len(),
155205

156206
// This is NOT readonly because no kernel mechanism prevents this
157207
// task and the caller task from sharing memory, including the
@@ -167,10 +217,12 @@ pub fn sys_set_timer(deadline: Option<u64>, notifications: u32) {
167217
syscall_asm!(
168218
Sysnum::Timer,
169219

220+
// r7 must be first, see syscall_asm
221+
in("r7") notifications,
222+
170223
in("r4") deadline.is_some() as u32,
171224
in("r5") raw_deadline as u32,
172225
in("r6") (raw_deadline >> 32) as u32,
173-
in("r7") notifications,
174226

175227
options(nomem, preserves_flags, nostack),
176228
);
@@ -189,10 +241,12 @@ pub fn sys_borrow_read(
189241
syscall_asm!(
190242
Sysnum::BorrowRead,
191243

244+
// r7 must be first, see syscall_asm
245+
in("r7") dest.as_mut_ptr(),
246+
192247
inlateout("r4") lender.0 as u32 => rc,
193248
inlateout("r5") index => length,
194249
in("r6") offset,
195-
in("r7") dest.as_mut_ptr(),
196250
in("r8") dest.len(),
197251

198252
options(readonly, preserves_flags, nostack),
@@ -213,10 +267,12 @@ pub fn sys_borrow_write(
213267
syscall_asm!(
214268
Sysnum::BorrowWrite,
215269

270+
// r7 must be first, see syscall_asm
271+
in("r7") src.as_ptr(),
272+
216273
inlateout("r4") lender.0 as u32 => rc,
217274
inlateout("r5") index => length,
218275
in("r6") offset,
219-
in("r7") src.as_ptr(),
220276
in("r8") src.len(),
221277

222278
// This is NOT readonly because no kernel mechanism prevents this

0 commit comments

Comments
 (0)