mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-10 12:32:45 +00:00
hv: extend the AC bit of rflags operations for smap
For apl_sdc_stable branch, we now have stac and clac to set and clear AC bit of rflags. But it can't handle following sequence: stac stac clac user mode address access here will trigger page fault clac This patch introduce two more functions: - stac_save: Save the rflags and set AC bit - ac_restore: Restore the AC bit saved to rflags Now, only sbuf_put/get are using these new APIs. Tracked-On: #2525 Signed-off-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
9f9750051d
commit
0cdc13fa0e
@ -29,10 +29,11 @@ uint32_t sbuf_get(struct shared_buf *sbuf, uint8_t *data)
|
|||||||
{
|
{
|
||||||
const void *from;
|
const void *from;
|
||||||
uint32_t ele_size;
|
uint32_t ele_size;
|
||||||
|
uint64_t rflags;
|
||||||
|
|
||||||
stac();
|
stac_save(&rflags);
|
||||||
if (sbuf_is_empty(sbuf)) {
|
if (sbuf_is_empty(sbuf)) {
|
||||||
clac();
|
ac_restore(&rflags);
|
||||||
/* no data available */
|
/* no data available */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -44,7 +45,7 @@ uint32_t sbuf_get(struct shared_buf *sbuf, uint8_t *data)
|
|||||||
sbuf->head = sbuf_next_ptr(sbuf->head, sbuf->ele_size, sbuf->size);
|
sbuf->head = sbuf_next_ptr(sbuf->head, sbuf->ele_size, sbuf->size);
|
||||||
|
|
||||||
ele_size = sbuf->ele_size;
|
ele_size = sbuf->ele_size;
|
||||||
clac();
|
ac_restore(&rflags);
|
||||||
|
|
||||||
return ele_size;
|
return ele_size;
|
||||||
}
|
}
|
||||||
@ -72,9 +73,10 @@ uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data)
|
|||||||
void *to;
|
void *to;
|
||||||
uint32_t next_tail;
|
uint32_t next_tail;
|
||||||
uint32_t ele_size;
|
uint32_t ele_size;
|
||||||
|
uint64_t rflags;
|
||||||
bool trigger_overwrite = false;
|
bool trigger_overwrite = false;
|
||||||
|
|
||||||
stac();
|
stac_save(&rflags);
|
||||||
next_tail = sbuf_next_ptr(sbuf->tail, sbuf->ele_size, sbuf->size);
|
next_tail = sbuf_next_ptr(sbuf->tail, sbuf->ele_size, sbuf->size);
|
||||||
/* if this write would trigger overrun */
|
/* if this write would trigger overrun */
|
||||||
if (next_tail == sbuf->head) {
|
if (next_tail == sbuf->head) {
|
||||||
@ -82,7 +84,7 @@ uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data)
|
|||||||
sbuf->overrun_cnt += sbuf->flags & OVERRUN_CNT_EN;
|
sbuf->overrun_cnt += sbuf->flags & OVERRUN_CNT_EN;
|
||||||
if ((sbuf->flags & OVERWRITE_EN) == 0U) {
|
if ((sbuf->flags & OVERWRITE_EN) == 0U) {
|
||||||
/* if not enable over write, return here. */
|
/* if not enable over write, return here. */
|
||||||
clac();
|
ac_restore(&rflags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
trigger_overwrite = true;
|
trigger_overwrite = true;
|
||||||
@ -99,7 +101,7 @@ uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data)
|
|||||||
sbuf->tail = next_tail;
|
sbuf->tail = next_tail;
|
||||||
|
|
||||||
ele_size = sbuf->ele_size;
|
ele_size = sbuf->ele_size;
|
||||||
clac();
|
ac_restore(&rflags);
|
||||||
|
|
||||||
return ele_size;
|
return ele_size;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,9 @@
|
|||||||
#define CR4_SMAP (1UL<<21U)
|
#define CR4_SMAP (1UL<<21U)
|
||||||
#define CR4_PKE (1UL<<22U) /* Protect-key-enable */
|
#define CR4_PKE (1UL<<22U) /* Protect-key-enable */
|
||||||
|
|
||||||
|
#define RFLAGS_C (1U<<0U)
|
||||||
|
#define RFLAGS_Z (1U<<6U)
|
||||||
|
#define RFLAGS_AC (1U<<18U)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entries in the Interrupt Descriptor Table (IDT)
|
* Entries in the Interrupt Descriptor Table (IDT)
|
||||||
@ -542,6 +545,23 @@ static inline void clac(void)
|
|||||||
asm volatile ("clac" : : : "memory");
|
asm volatile ("clac" : : : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save rflags register and set AC bit */
|
||||||
|
static inline void stac_save(uint64_t *p_rflags)
|
||||||
|
{
|
||||||
|
CPU_RFLAGS_SAVE(p_rflags);
|
||||||
|
asm volatile ("stac" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore AC bit saved in p_rflags */
|
||||||
|
static inline void ac_restore(uint64_t *p_rflags)
|
||||||
|
{
|
||||||
|
if (*p_rflags & RFLAGS_AC) {
|
||||||
|
stac();
|
||||||
|
} else {
|
||||||
|
clac();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else /* ASSEMBLER defined */
|
#else /* ASSEMBLER defined */
|
||||||
|
|
||||||
#endif /* ASSEMBLER defined */
|
#endif /* ASSEMBLER defined */
|
||||||
|
Loading…
Reference in New Issue
Block a user