mirror of https://github.com/RPCS3/rpcs3.git
rsx: Fix memory protection
- Fixes hanging when wcb is enabled
This commit is contained in:
parent
479aa91368
commit
86bf61ad35
|
@ -209,7 +209,7 @@ namespace rsx
|
||||||
if (tex.is_dirty()) continue;
|
if (tex.is_dirty()) continue;
|
||||||
if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better
|
if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better
|
||||||
|
|
||||||
auto overlapped = tex.overlaps_page(trampled_range, address);
|
auto overlapped = tex.overlaps_page(trampled_range, address, false);
|
||||||
if (std::get<0>(overlapped))
|
if (std::get<0>(overlapped))
|
||||||
{
|
{
|
||||||
auto &new_range = std::get<1>(overlapped);
|
auto &new_range = std::get<1>(overlapped);
|
||||||
|
@ -277,9 +277,9 @@ namespace rsx
|
||||||
auto &tex = range_data.data[i];
|
auto &tex = range_data.data[i];
|
||||||
|
|
||||||
if (tex.is_dirty()) continue;
|
if (tex.is_dirty()) continue;
|
||||||
if (!tex.is_flushable()) continue;
|
if (!tex.is_locked()) continue;
|
||||||
|
|
||||||
auto overlapped = tex.overlaps_page(trampled_range, address);
|
auto overlapped = tex.overlaps_page(trampled_range, address, true);
|
||||||
if (std::get<0>(overlapped))
|
if (std::get<0>(overlapped))
|
||||||
{
|
{
|
||||||
auto &new_range = std::get<1>(overlapped);
|
auto &new_range = std::get<1>(overlapped);
|
||||||
|
@ -292,12 +292,20 @@ namespace rsx
|
||||||
range_reset = true;
|
range_reset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Defer actual flush operation until all affected regions are cleared to prevent recursion
|
if (tex.is_flushable())
|
||||||
|
{
|
||||||
|
sections_to_flush.push_back(&tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_unreleased_texture_objects++;
|
||||||
|
tex.set_dirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
tex.unprotect();
|
tex.unprotect();
|
||||||
sections_to_flush.push_back(&tex);
|
range_data.remove_one();
|
||||||
|
|
||||||
response = true;
|
response = true;
|
||||||
range_data.remove_one();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -835,7 +835,7 @@ namespace rsx
|
||||||
|
|
||||||
const auto window_origin = rsx::method_registers.shader_window_origin();
|
const auto window_origin = rsx::method_registers.shader_window_origin();
|
||||||
const u32 window_height = rsx::method_registers.shader_window_height();
|
const u32 window_height = rsx::method_registers.shader_window_height();
|
||||||
const f32 resolution_scale = (window_height <= g_cfg.video.min_scalable_dimension)? 1.f : rsx::get_resolution_scale();
|
const f32 resolution_scale = (window_height <= (u32)g_cfg.video.min_scalable_dimension)? 1.f : rsx::get_resolution_scale();
|
||||||
const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
|
const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
|
||||||
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
|
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ namespace rsx
|
||||||
u32 cpu_address_range = 0;
|
u32 cpu_address_range = 0;
|
||||||
|
|
||||||
utils::protection protection = utils::protection::rw;
|
utils::protection protection = utils::protection::rw;
|
||||||
|
protection_policy guard_policy;
|
||||||
|
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -115,6 +116,7 @@ namespace rsx
|
||||||
locked_address_range = align(base + length, 4096) - locked_address_base;
|
locked_address_range = align(base + length, 4096) - locked_address_base;
|
||||||
|
|
||||||
protection = utils::protection::rw;
|
protection = utils::protection::rw;
|
||||||
|
guard_policy = protect_policy;
|
||||||
locked = false;
|
locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +172,7 @@ namespace rsx
|
||||||
* Check if the page containing the address tramples this section. Also compares a former trampled page range to compare
|
* Check if the page containing the address tramples this section. Also compares a former trampled page range to compare
|
||||||
* If true, returns the range <min, max> with updated invalid range
|
* If true, returns the range <min, max> with updated invalid range
|
||||||
*/
|
*/
|
||||||
std::tuple<bool, std::pair<u32, u32>> overlaps_page(std::pair<u32, u32> old_range, u32 address) const
|
std::tuple<bool, std::pair<u32, u32>> overlaps_page(std::pair<u32, u32> old_range, u32 address, bool full_range_check) const
|
||||||
{
|
{
|
||||||
const u32 page_base = address & ~4095;
|
const u32 page_base = address & ~4095;
|
||||||
const u32 page_limit = address + 4096;
|
const u32 page_limit = address + 4096;
|
||||||
|
@ -178,10 +180,25 @@ namespace rsx
|
||||||
const u32 compare_min = std::min(old_range.first, page_base);
|
const u32 compare_min = std::min(old_range.first, page_base);
|
||||||
const u32 compare_max = std::max(old_range.second, page_limit);
|
const u32 compare_max = std::max(old_range.second, page_limit);
|
||||||
|
|
||||||
if (!region_overlaps(locked_address_base, locked_address_base + locked_address_range, compare_min, compare_max))
|
u32 memory_base, memory_range;
|
||||||
|
if (full_range_check && guard_policy != protection_policy::protect_policy_full_range)
|
||||||
|
{
|
||||||
|
//Make sure protection range is full range
|
||||||
|
memory_base = (cpu_address_base & ~4095);
|
||||||
|
memory_range = align(cpu_address_base + cpu_address_range, 4096u) - memory_base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memory_base = locked_address_base;
|
||||||
|
memory_range = locked_address_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!region_overlaps(memory_base, memory_base + memory_range, compare_min, compare_max))
|
||||||
return std::make_tuple(false, old_range);
|
return std::make_tuple(false, old_range);
|
||||||
|
|
||||||
return std::make_tuple(true, get_min_max(std::make_pair(compare_min, compare_max)));
|
const u32 _min = std::min(memory_base, compare_min);
|
||||||
|
const u32 _max = std::max(memory_base + memory_range, compare_max);
|
||||||
|
return std::make_tuple(true, std::make_pair(_min, _max));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_locked() const
|
bool is_locked() const
|
||||||
|
|
Loading…
Reference in New Issue