Risc-V extension for dismissible loads - cpu-architecture

Certain architectures have "dismissible loads" in addition to normal loads: when the load is denied, instead of issuing an exception (leading to a segmentation fault), a default value (e.g., zero) is written to the destination register. This allows the compiler to move loads before a conditional branch, which may be important for performance on non speculative cores.
I was wondering if there was a Risc-V extension for this. I haven't found any.

There is no support for dismissible loads (i.e. load instructions that do not trap based on the memory protections of a memory location, when a standard lw, lh, lb etc. would trap) among the current set of complete standard RISC-V extensions. They wouldn't fit naturally in any of the planned standard extensions either. You can find the current version of the ISA specification here. (Standard extensions are designed and approved by the RISC-V foundation, are guaranteed not to conflict with each other, and will appear in the ISA specification).
That being said, RISC-V was designed to make it straightforward to design and implement non-standard extensions for custom accelerators. There are certain bits reserved for the implementation of custom extensions, with a guarantee that current and future standard extensions will not conflict. So there's also nothing in place to prevent adding a dismissible load instruction to RISC-V as part of a non-standard extension.

Related

ebpf: bpf_prog_load() vs bpf_object__load()

I have not used libbpf in a while. Now, when I'm looking at the source code and examples, it looks to me that all API now is built around bpf_object while before it was based on program FD (at least on the user-facing level). I believe that fd is now hidden in bpf_object or such.
Of course it keeps backward compatibility and I still can use bpf_prog_load for example, however it looks like the preferred way of writing application code using libbpf is by bpf_object API?
Correct me if I'm wrong. Thanks!
Sounds mostly correct to me.
Low-Level Wrappers
If I remember correctly, the functions returning file descriptors in libbpf, mostly defined in tools/lib/bpf/bpf.c, have always been very low-level. This is the case for bpf_load_program() for example, which is no more than a wrapper around the bpf() system call for loading programs. Such functions are still available, but their use may be tedious for complex use cases.
bpf_prog_load()
Some more advanced functions have long been provided. bpf_prog_load(), that you mention, is one of them, but it returns an error code, not a file descriptor. It is still available as one option to load programs with the library.
bpf_object__*()
Although I don't think there are strict guidelines, I believe it is true that most example now use the bpf_object__*() function. One reason is that they provide a more consistent user experience, being organised around the manipulation of an object file to extract all the relevant bytecode and metadata, and then to load and attach the program. One other reason, I think, is that since this model has been favoured over the last releases, these functions have better support for recent eBPF features and the bpf_object__*() functions offer features that the older bpf_prog_load() workflow does not support.
Libbpf Evolves
At last, it's worth mentioning that libbpf's API is currently undergoing some review and will likely be reworked as part of a major v1.0 release. You may want to have a look at the work document linked in the announcement: Some bpf_object__ functions may be deprecated, and similarly there is currently a proposal to:
Deprecate bpf_prog_load() and bpf_prog_load_xattr() in favor of bpf_object__open_{mem, file}() and bpf_object__load() combo.
There is nothing certain yet regarding the v1.0 release, so I wouldn't worry too much about “deprecation” at the moment - I don't expect all functions to be removed just yet. But that's something you may want to consider when building your next applications.

Sandboxing Guile by deleting unwanted libraries?

I have an open-source GUI for which I've just implemented a very basic extension mechanism that allows the user to embed a snippet of Lisp (Guile) code in a document to allow certain functions to be customized. Currently the use case (my own) is that in a certain situation I just want a certain number to be divided by 10 automatically.
In principle this means that if someone uses my GUI, someone else can send them a document containing a Trojan horse attack in the form of malicious Guile code. This seems unlikely in reality due to my very small user base and the relevant social factors, but anyway I would like to protect against this by sandboxing the code.
Guile 2.2.1 has a sandboxing mechanism: https://www.gnu.org/software/guile/manual/html_node/Sandboxed-Evaluation.html However, this seems entirely focused on preventing excessive use of resources (and many users will not have such a current version of Guile, e.g., I don't right now).
Is it possible in a Guile program, after the interpreter has started up, to delete libraries such as POSIX so that any later code can't do things like read files? If so, then I could just have my GUI prepend the sandboxing code to the potentially untrusted code supplied by the document. My goal would basically be to ensure that the untrusted code would have to be 100% without side effects.
It seems like other people must have run into this issue before, since Guile has been promoted as a standard extension language for Linux.
EDIT: After coming across How to undefine a variable in Scheme? , it seems to me that I could probably create a new scope, override the definition of any dangerous function by doing a set! within that scope, and then execute the untrusted code within that scope. I suppose if I could read the entire symbol table somehow, I could do this kind of overriding on every function that isn't on a whitelist. This just seems clumsy and inefficient, and might depend on reading the symbol table using some implementation-specific mechanism. It also might be vulnerable to syntactical tricks, like if the untrusted code uses a ) to pop itself out of the scope of the sandbox.

Using SIMD instructions in application oriented to multiple platforms and OS

So, no matter how much I read about SIMD instructions, there is something basic I still can't understand properly and would, therefore, love to have some (conceptual) explanation or suggestions about.
I understand that the many SIMD implementations vary from one CPU architecture to another (MMX, SSE, SSE2, etc). However, considering that since the middle of the 2000s there seems to have been greater convergence between SIMD instructions-sets across Intel and AMD (and Apple has started used Intel), I don't get the following.
Simply put, if an application has a specific SIMD code (e.g. for a vectorized math library), would it equally run in both Intel's and AMD's (therefore in Windows and Linux computers) and also in iOS without any modification?
Or would it be required that specific code is implemented for each CPU architecture/operational system that is target by the application, in a way that different compilations of the application are given for each user type?
For Intel/AMD there can be some convergence, depending on how hard you want to push the performance envelope. iOS devices are ARM-based though, and use Neon SIMD rather than Intel/AMD's SSE/AVX, so there is no binary compatibility and only minimal compatibility at the source level (e.g. via macros or template libraries). See this question for some cross-platform solutions.

Static code analysis / Code annotations

I am writing code which is working like a state machine. So:
some functions are setting a specific state
others are allowed to be executed in a specific state.
(In reality it is a little more complex, but these are the basics, to keep it simple.)
Currently I use runtime assertions to check if a function is allowed in the current state. This is nice because it is kind of self documenting; moreover I can stop with the debugger on an assert and know where the error is. But the drawback is that it requires compiling the code, and that during testing I need to find custom inputs to fire the appropriate assertions.
Incidentally, I know that the Windows WDK provides annotations such as:
__drv_maxIRQL
__drv_setsIRQL
These annotations are statically checked using PreFAST, which can fire an error if necessary. This kind of static verification of code specifications is exactly what I need.
So the question is: are there any tools out there which provide similar functionality for programs specified in the form of state machines?
The Frama-C plug-in Aoraï does more or less exactly what you describe, for C programs, with the possibility of static verification. It does not rely on PreFAST but on comparable verification tools from the Frama-C platform.

Does evolution of microprocessors warrants evolution of compilers and language standards?

As chip makers add new functions, instructions etc to new chips, do we need newer versions of the compilers accordingly to use those new instructions and features of the chip? Also does it mean that programming language also needs new opcodes,syntax etc to use the new features of the chip?
Yes, new hardware features are reflected in language extensions and in new languages. For example, see the various vector extensions for C and C++ that reflects the availability of SIMD instructions, and the new derived data-parallel languages like CUDA and OpenCL.
If the hardware is significantly different from the others, it is likely that it will require its own, different programming language, see the late Transputers and their Occam language.
Compilers that compile to machine code (not to a VM) might need to change any time its target architecture changes (although ideally all changes would be backward compatible, so that additions just mean there's new optimizations possible, but that old compilers would still work).
Programming languages don't need to change, but might if a desirable feature is made newly possible by a change in the machine's capabilities. Unless, by "programming languges" you mean assembly/machine language, in which case a one to one chip-instruction to assembly/machine instruction probably ought to be (but doesn't have to be) be added.
Notice all the "might"s. Chances are that these changes are invisible to you unless you're working in Assembly, Machine code, compiler design, or programming language design. If you're not, then worrying yourself about these things is a waste of your time.