2. Do like your proposal does (as I understand it) and have the number
of available bits for use as a tag dependent on the supported virtual
address space. A program written assuming an Sv39 system and hence 24
bits of tag is going to have a bad time upon a move to Sv48 or higher
3. Support setting a mask for address translation that is independent
of the virtual addressing mode. More complex than the above two
options as you have to consider the case where bits are masked that
otherwise would be used in virtual address translation. The advantage
is processes might opt-in to masking on a case-by-case basis and make
the choice of trading off virtual address space for tags. e.g. even
under Sv48 I could make use of 24-bit tags. It does of course add more
per-process state and would need co-operation from mmap and friends
For all options (even 1. and 2. that have minimal implementation
complexity), I feel it would be useful to justify the potential hassle
in terms of benchmarks.
I suspect that the idea with this is that this would be something that could differ per-process, and thus could be specified in the binary format (something something ELF?).
Then it'd be less about "a move to Sv48 or higher" and more about "realizing that this particular program actually does need that much memory sometimes."
It's still a footgun for future-proof code, but less of one than it otherwise might be - programs would encounter it individually and organically, as they grew to use larger amounts of memory / operate on larger data sets, without it impeding ports to a new architecture.
Personally, I'd specify the metadata as specifying _minimum number of tag bits_, as that's independent of CPU architecture. The user code, then, would compute `(sizeof(*void) * CHAR_BIT) - DESIRED_TAG_BITS` to find how much it should left-shift its tags by.
Heck, you could do this:
```C
#ifndef TAG_BITS
#define TAG_BITS 0
#endif
#define TAG_MASK ((1 << TAG_BITS) - 1)
#define POINTER_BITS \
(sizeof(*void) * CHAR_BIT) - TAG_BITS
#define POINTER_MASK ((((uintptr_t)1) << POINTER_BITS) - 1)
#define SET_TAG(ptr, tag) \
((((ptr) & POINTER_MASK) | (((tag) & TAG_MASK) << POINTER_BITS))
```
That, at least, minimizes portability issues caused by _improved hardware_ - moving from RV64 to RV128 would essentially never break such code, so long as the supervisor supports per-process page table depth.
Similarly, by using a field in the binary format, attempting to run such a piece of code can emit clear, early errors to the user.
On 25 Sep 2016, at 1:39 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:3. Support setting a mask for address translation that is independent
of the virtual addressing mode. More complex than the above two
options as you have to consider the case where bits are masked that
otherwise would be used in virtual address translation. The advantage
is processes might opt-in to masking on a case-by-case basis and make
the choice of trading off virtual address space for tags. e.g. even
under Sv48 I could make use of 24-bit tags. It does of course add more
per-process state and would need co-operation from mmap and friends
This 3rd option is essentially a means to squeeze every last bit of address space compatible with a given tag length. It requires considerably more hardware and allocating CSRs, which my proposal intentionally avoids in order to justify requiring support for UAM/SAM.
On 25 Sep 2016, at 1:09 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:A binary translator on an architecture that mandates “canonical addresses” will be able to retranslate inserting masking loads and stores when this feature is active.
Although this raises a separate issue that I had been thinking about (for userland sandboxes), and that is an option to make FENCE.I require S mode privileges and have an option for it fault in U mode. I don’t know if FENCI.I virtualizable? It seems to be a candidate for a trapping instruction in U mode. Alternatively a strict loader could raise a verifier exception for a well formed subset of RISC-V in ELF upon seeing FENCE.I. It did occur to me that FENCE.I is something that may wish to be administratively disabled on a per process basis. i.e. exceptions to be made for JITs. Self-modifying code is pretty obscure these days, and is usually an obfuscation or attack vector.
The problem is that FENCE.I only guarantees that instruction fetch will see modifications. Do enough other accesses to flush caches and you achieve the same effect, just with less efficiency, which I doubt will cause an exploit writer to fret overmuch. Lack of FENCE.I does not guarantee that modifications to program text will not be seen. An implementation could do an implicit "FENCE; FENCE.I; SFENCE.VM" after every STORE. Simple embedded processors, with only internal SRAM, probably will. (But those probably will not support S-mode at all, so no SFENCE.VM.)
On Sat, Sep 24, 2016 at 9:29 AM, Alex Bradbury <a...@asbradbury.org> wrote:
> If I understand correctly, this is basically a variant of my 'option
> 3' suggestion but with a different mask per register. Although this
> increases flexibility, the downsides of all that extra per-process
> state seem rather high. I'm struggling to think of a killer use-case
> for having a different mask for reach register?
Two responses to this question. The first response addresses why
multiple-masks are useful, without regard to any particular mapping or
quantity of mask registers.
In 1984, Commodore-Amiga asked Microsoft for a version of BASIC to use
on the Amiga 1000. They came up with AmigaBASIC 1.0, which shipped
with AmigaOS 1.1 IIRC, definitely with AmigaOS 1.2. (AmigaOS 1.0 had
ABasiC, which they used as MS was late in its delivery.) This product
worked pretty great on the 68000 and 68010 CPUs. It crashed hard on
68020 and later CPUs though. The reason is that it used the upper
8-bits of some types of pointers as flags.
--
You received this message because you are subscribed to the Google Groups "RISC-V ISA Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isa-dev+u...@groups.riscv.org.
To post to this group, send email to isa...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/isa-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/isa-dev/CAEz%3Dson9YL9CMsufG_KuPbehkmTXZvdqARwwSRRifk2%3Do6wfSw%40mail.gmail.com.